我自己的应用程序使用与2016年Google I / O应用程序所示完全相同的技术.see source
我需要在非常具体的时间点提醒用户 - 使用通知。
为此,我使用AlarmManager
在正确的时间点唤醒设备:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
am.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
} else {
am.set(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
}
pendingIntent
是这样创建的:
final Intent intent = new Intent(MyAlarmService.ACTION_NOTIFY_RIDE, null, this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
现在,我的MyAlarmService
类是一个简单的IntentService
处理唤醒只是为了为用户创建通知。
我在日志中收到的消息如下:
W/ActivityManager: Background start not allowed: service Intent { act=xxx.xxx.xxx.action.NOTIFY_RIDE flg=0x4 cmp=xxx.xxx.xxx./xxx.xxx.xxx.service.MyAlarmService (has extras) }
现在,谷歌自己的实施显然已被打破 - 即使我不想做任何繁重的背景工作,我也不能再使用这种技术了。但是,我应该如何在非常具体的时间点唤醒用户呢? (想想我的应用程序作为闹钟)
我的问题的答案简单明了:
而不是使用服务来显示通知(就像谷歌在其IO计划应用程序中所做的那样!),使用BroadcastReceiver!
我不知道为什么Google确实使用了IntentService,但现在在Android O上,由于后台执行限制,这根本不再起作用了。
尽管BroadcastReceiver显然仍然可以运行一小段时间并显示通知。
如果有人可以告诉我为什么谷歌首先使用IntentService,那么奖励积分......这花了我很多时间才弄明白,因为我认为谷歌知道他们在做什么...... :(
但是,我应该如何在非常具体的时间点唤醒用户呢? (想想我的应用程序作为闹钟)
首先,您的代码不准确。如果设备处于打盹模式,我预计最多+/- 10分钟。如果您想要精确的计时,并且您的应用程序确实是一个闹钟,请使用setAlarmClock()
。
对于您现有的代码,use getForegroundService()
而不是API Level 26+上的getService()
。
您甚至可以考虑定期运行SyncAdapter / Job Scheduler来执行相同的业务逻辑。要设置新的定期同步,您可以首次在Application Launch Itself上进行。