【发布时间】:2019-08-27 16:16:45
【问题描述】:
我有以下要求。用户需要能够在我的应用中安排定期提醒,以便在每天准确的时间触发推送通知。
这是我希望我最终不会提交的问题之一,因为在编写它时推荐了类似的问题。然而,一些团队成员已经花费了数小时查看 Android 开发人员文档和 Stackoverflow,我们似乎离答案更近了,所以我们来了。
如果我创建一个提醒并将其设置为在未来 5 分钟触发通知,则通知会正常触发。
我怀疑这可能是由 Android P 中引入的电池节省、唤醒锁定等更改引起的问题,因为在将目标 SDK 更新到 28 之前我们没有这个问题。话虽如此,我并不肯定这是唯一的问题,但我可以在运行 Android P 的 Pixel 和 Pixel 3 XL 上始终如一地重现该问题。
当用户将提醒设置为半夜的某个时间(大概是当用户睡着,因此几个小时都不会使用手机时)时,会发生通知未触发的示例。这些提醒永远不会触发。
我目前正在尝试使用警报管理器来完成此操作。
这个问题似乎与另一个使用Alarm Manager's setRepeating 方法的问题相似,我们发现该方法不起作用。我们改为使用警报管理器的 setExactAndAllowWhileIdle 方法。我们还使用警报管理器setAlarmClock 方法尝试了相同的实现,根据 Android 文档“即使系统处于低功耗空闲(又名打瞌睡)模式,也将允许触发该方法”但是这也是不成功的。
我怀疑这不起作用的原因是因为 setExactAndAllowWhileIdle 在手机处于打盹模式时不会触发,类似于this question 中表达的问题。这个问题建议使用 Firebase JobDispatcher,但由于这是一个内部通知,我需要在有或没有网络连接的情况下触发通知,这似乎消除了 Firebase JobDispatcher 作为一个选项。这个问题还表明,一旦手机退出打盹模式,用户就会收到通知,但是我们永远不会收到通知,他们似乎因为缺乏更好的术语而迷失了方向。
我已将唤醒锁定权限添加到我的 AndroidManifest.xml:
<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);
}
}
}
【问题讨论】:
-
出于类似的原因,我将这个库与作业调度程序一起使用github.com/evernote/android-job
-
这是一个教科书示例,其中包含一个经过深思熟虑和制定的堆栈溢出问题。
标签: android notifications alarmmanager android-9.0-pie android-doze