27

この質問は何度も聞かれると思いますstackoverflowが、それでも多くの人が解決に苦労しています。

私のAndroidアプリでは、現在の場所を取得してサーバーに送信するために、30分ごとにデバイスを起動する必要があります。このために、メソッドとを使用AlarmManagerしました。samsung、LG(Nexus)、Sony、Panasonic、lenovo、Motorola、Micro max などのほとんどすべての標準/人気デバイスで正常に動作します....しかし、他のいくつかのデバイスは、主に中国のデバイスをサポートしていないか、デバイスのウェイクアップを許可できませんで居眠りモードから。特定の間隔でアラーム マネージャを起動できないデバイスでテストしました。setExactAndAllowWhileIdle()WakefulBroadcastReceiversetExactAndAllowWhileIdle()leeco letV (Android OS 6.1)

私が以下に言及した私のコード部分:

UserTrackingReceiverIntentService.java

public class UserTrackingReceiverIntentService extends IntentService {

    public static final String TAG = "UserTrackingReceiverIntentService";
    Context context;
    public UserTrackingReceiverIntentService() {
        super("UserTrackingReceiverIntentService");
    }

    @TargetApi(Build.VERSION_CODES.M)
    @Override
    protected void onHandleIntent(Intent intent) {
        this.context = this;

        if (!Util.isMyServiceRunning(LocationService.class, context)) {
            context.startService(new Intent(context, LocationService.class));
        }

        Calendar calendar = Calendar.getInstance();
        //********************************** SETTING NEXT ALARM *********************************************
            Intent intentWakeFullBroacastReceiver = new Intent(context, SimpleWakefulReceiver.class);
            PendingIntent sender = PendingIntent.getBroadcast(context, 1001, intentWakeFullBroacastReceiver, 0);
            AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);

        if (calendar.get(Calendar.MINUTE) >= 0 && calendar.get(Calendar.MINUTE) < 30) {
            calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
            calendar.set(Calendar.MINUTE, 30);
            calendar.set(Calendar.SECOND, 0);
        } else if (calendar.get(Calendar.MINUTE) >= 30) {
            if (calendar.get(Calendar.HOUR_OF_DAY) == 23) {
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            } else {
                calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
            }
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
        } else {
            calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
        }

        //MARSHMALLOW OR ABOVE
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), sender);
        }
        //LOLLIPOP 21 OR ABOVE
        else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(calendar.getTimeInMillis(), sender);
            alarmManager.setAlarmClock(alarmClockInfo, sender);
        }
        //KITKAT 19 OR ABOVE
        else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            alarmManager.setExact(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), sender);
        }
        //FOR BELOW KITKAT ALL DEVICES
        else {
            alarmManager.set(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), sender);
        }


        Util.registerHeartbeatReceiver(context);
        SimpleWakefulReceiver.completeWakefulIntent(intent);
    }
}

上記のサービスが呼び出されるたびに、30分後に次のアラームが設定されます。

public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // This is the Intent to deliver to our service.
        Calendar calendar = Calendar.getInstance();
        Intent service = new Intent(context, UserTrackingReceiverIntentService.class);
        Date date = new Date();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        String DateTime = sdf.format(date);
        DateTime = Util.locatToUTC(DateTime);
        service.putExtra("date", String.valueOf(DateTime));

        String latitude = Util.ReadSharePrefrence(context, "track_lat");
        String longitude = Util.ReadSharePrefrence(context, "track_lng");

        service.putExtra("lat", latitude);
        service.putExtra("lon", longitude);

        Log.i("SimpleWakefulReceiver", "Starting service @ " + calendar.get(Calendar.HOUR_OF_DAY) + " : " + calendar.get(Calendar.MINUTE) + " : " + calendar.get(Calendar.SECOND));

        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, service);
    }
}

leeco letV[設定] > [バッテリー] > [ウェイクアップの調整] > [両方のオプションを無効にする] などのデバイスから手動で設定を変更したためです。有効にすると、バッテリーはアプリからの強制ウェイクアップを無視できます。

私の質問:

  1. そのような種類のデバイスで何が起こったのですか?特定の時間間隔でアラームを発することを許可しないのはなぜですか?

  2. Gionee s plus のような一部のデバイスでは、アラームが 2 ~ 3 分遅れて作動します...なぜですか?

  3. android.net.conn.CONNECTIVITY_CHANGEネットワーク接続が変更されたときにリッスンするブロードキャスト レシーバー .....Gionee s plus のような一部のデバイスで機能しない場合はどうすればよいですか?

  4. さまざまなメーカーのバッテリー最適化設定には多くのバリエーションがあります....これに対する解決策がある場合、アプリのバックグラウンド サービスに害を及ぼす可能性があります。

4

4 に答える 4

3

こんにちは、Xiomi phone.leeco でのテスト中に同じ問題が発生しました。よくわかりません。Xiomi電話にはMIUIという独自のOSがあります。RAMをクリアすると、一部のアプリを除くすべてのアプリがOSに登録されます。Whatsapp や facebook のように、他の有名なアプリもあります。

Service、Alarm Manager、および Scheduler を試しましたが、成功しませんでした。

それらは、サービスを実行するための手動で特定の方法を提供します.LeecoがAndroid OSを使用していることを確認しました.

MIUI 7.0 のソリューション => セキュリティ => 自動起動 => バックグラウンドで実行するアプリを選択 => 再起動 再起動 後、デバイスは他の Android デバイスと同様にバックグラウンドでアプリケーション サービスを実行できるはずです。

MIUI 4.0 の設定

MIUI AutoStart 詳細説明

私によると、サービスを試してから、それが機能するかどうかを確認できます。

うまくいけば、これで少し助けが得られます。

于 2016-12-12T13:53:27.967 に答える
1

仰るとおりです。でもJobSchedulerは一度試してみるといいと思います。公式ドキュメントが見つかり ますhttps://developer.android.com/reference/android/app/job/JobScheduler.html私が 見つけた最良の例 https://github.com/googlesamples/android-JobScheduler 私はそれをテストしていません.私によると、これを試してみる必要があります。

編集

6.0 以降でアプリケーションを Doze モードで実行する場合は、アプリケーションのチェックアウトをホワイト リストに登録する必要があります。

https://www.bignerdranch.com/blog/diving-into-doze-mode-for-developers/

https://developer.android.com/training/monitoring-device-state/doze-standby.html

イムティヤズ

于 2016-12-13T05:09:32.813 に答える