web-dev-qa-db-ja.com

DozeモードでAndroid 6.0のときにAlarm Managerを動作させる方法は?

私は、Google Playの2つの目覚まし時計アプリの開発者です。私はそれらをAndroid 6.0で動作させようとしています。しかし、Dozeモードはそれらが鳴らないようにします。他に何ができるかわからない-居眠りモードでは、アラームマネージャーのアラームはまだ無視されます。ただし、時計アプリ(AOSPアプリではなくGoogle Play)は異なります。時計アプリの「adb deviceidle step」は常に「active」と表示され、「idle」、「idle_pending」などは表示されません。

Androidここで不正行為をし、独自のアプリにパワーを与えます。別名「アップルを引っ張る」?Google Playの目覚まし時計アプリはすべて機能しなくなりますか?ここで心配しているのは、それぞれが1年間のパートタイム開発時間を要した高品質のアプリであり、私にとっては大きな収入源です。

AlarmManagerインテントの設定:

        Intent intent = new Intent(context, ReceiverAlarm.class);
        if (Android.os.Build.VERSION.SDK_INT >= 16) {
            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        }
        amSender = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_CANCEL_CURRENT); //FLAG_CANCEL_CURRENT seems to be required to prevent a bug where the intent doesn't fire after app reinstall in KitKat
        am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        am.set(AlarmManager.RTC_WAKEUP, scheduleToTime+1, amSender);

およびReceiverAlarmクラス:

public class ReceiverAlarm extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
    if (wakeLock == null) {
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Theme.appTitle);
        wakeLock.acquire();
    }
    X.alarmMaster.startRingingAlarm(true);
}

x.alarmMaster.startRingingAlarm()メソッドの関連部分:

    if (wakeLock == null) {
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Theme.appTitle);
        wakeLock.acquire();
    }

    if (screenWakeLock == null) {
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        screenWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, Theme.appTitle+" scr");
        screenWakeLock.acquire();
    }

    Intent alarmIntent = new Intent(Intent.ACTION_VIEW);
    alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    alarmIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    alarmIntent.setClass(context, ActivityAlarmAlarm.class);

    context.startActivity(alarmIntent);

一部のメソッドは、読みやすくするためにインラインで貼り付けられています。

47
user1908060

居眠りとアプリスタンバイは、アラームとウェイクロックに関する動作を確実に変更しますが、それらは間違いなくあなたにとって世界の終わりではありません!

setAlarmclock()の代わりに set() メソッドを使用してみましたか?それは目覚まし時計専用に設計されており、居眠りをカットすることができるかもしれません。手動で電話機を居眠りモードまたはアプリスタンバイモードにするために使用できるいくつかのadbコマンドがあります。 https://developer.Android.com/preview/features/power-mgmt.html

それでアプリをウェイクアップできない場合は、確実な方法があります setExactAndAllowWhileIdle() は、何があっても携帯電話を居眠りからウェイクアップするように設計されています。最悪のシナリオでは、この方法でアプリをウェイクアップし、ウェイクアップを使用して次のアラームをスケジュールできます。

読む価値のある別のページは、バックグラウンド作業とアラームのフローチャートを含むこのブログ投稿です: https://plus.google.com/+AndroidDevelopers/posts/GdNrQciPwqo

34
ccpmark

アプリケーションをホワイトリストに入れると、ネットワークは居眠りモードになります。 AlarmManagerはホワイトリストの影響を受けません。

SetExactAndAllowWhileIdle()メソッドについては、SDKから以下の説明を確認してください。居眠りから携帯電話を起こすことはありません。

アラームがディスパッチされると、アプリは約10秒間システムの一時的なホワイトリストに追加され、そのアプリケーションが作業を完了するためにさらにウェイクロックを取得できるようになります。

2
Wonil