web-dev-qa-db-ja.com

AndroidアプリがDozeモードのときにアラームマネージャーによってトリガーされた通知が発生しない

次の要件があります。ユーザーは、毎日exact時刻にプッシュ通知をトリガーするアプリで定期的なリマインダーをスケジュールできる必要があります。

これは、作成中に同様の質問が推奨されたために提出しないことを望んでいた質問の1つです。しかし、数人のチームメンバーがAndroid開発者用ドキュメントとStackoverflowを調べて何時間も費やしてきました。私たちは答えに近づいていないようです。ここにあります。

リマインダーを作成し、5分後に通知をトリガーするように設定すると、通知は正常に起動します。

これは、Android Pで導入されたバッテリー節約、スリープ解除などの変更によって引き起こされた問題である可能性があります。ターゲットSDKを28に更新する前はこの問題がなかったためです。これが唯一の問題であると私は確信していませんが、PixelおよびPixel 3 XLを実行しているAndroid P.

たとえば、ユーザーがリマインダーを真夜中のどこかに設定した場合(おそらくユーザーが眠っており、したがって電話を数時間使用しなかった場合)に、通知が発生しない例が発生します。これらのリマインダーはこれまでに発生していません。

現在、アラームマネージャーを使用してこれを達成しようとしています。

この問題は、 アラームマネージャーのsetRepeating メソッドを使用する別の質問に似ているように見えますが、これは機能しません。代わりに、Alarm ManagerのsetExactAndAllowWhileIdleメソッドを使用しています。 Androidドキュメンテーション "に従って、システムが低電力状態にある場合でもトリガーできるようにする、Alarm Managers setAlarmClock メソッドを使用して、この同じ実装を試しました。アイドル(別名居眠り)モード」しかし、これも失敗しました。

これが機能しない理由は、電話がDozeモードのときにsetExactAndAllowWhileIdleが起動しないためであると考えられます。これは この質問 で表される問題と同様です。この質問はFirebase JobDispatcherの使用を推奨していますが、これは内部通知であるため、オプションとしてFirebase JobDispatcherを排除しているように見えるネットワーク接続の有無にかかわらず通知を起動する必要があります。この質問は、電話が居眠りモードを終了するとユーザーが通知を受け取るが、通知を受け取ることはないことを示しているため、より適切な用語がないために失われたように見えます。

私はAndroidManifest.xmlにwake lock権限を追加しました:

<uses-permission Android:name="Android.permission.WAKE_LOCK" />

これが私のレシーバーがAndroidManifest.xmlに登録される方法です

<receiver Android:name="com.myapp.receiver.AlarmReceiver">
    </receiver>

これが私の現在の実装です:

通知を処理するための保留中の意図

Intent i = new Intent(context, ScheduleAllReceiver.class);
    PendingIntent scheduleAllPendingIntent = PendingIntent.getBroadcast(context, SCHEDULER_DAILY_ALL, i, PendingIntent.FLAG_UPDATE_CURRENT);

続いて次のようにメソッド「createAlarm」を呼び出します

createAlarm(context, scheduleAllPendingIntent, calendar.getTimeInMillis());

アラームの作成

public static void createAlarm(Context context, PendingIntent pendingIntent, long timeinMilli) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

    if(alarmManager != null) {

        if (Build.VERSION.SDK_INT >= 23) {
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeinMilli, pendingIntent);
        } else {
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeinMilli, pendingIntent);
        }
    }
}
7
pat8719

これはライブラリです うまくいきました。

1
RSauther

はい、そうです。現在Googleでは、AlarmManagerの代わりに WorkManager を使用することをお勧めしています。 AlarmManagerの仕事には多くの制限があります。あなたはより多くの情報を見つけることができます ここ(ドーズモード)
また、pixel phoneには bug とalarmManagerがあります

0
Alexander