Android O和后台限制可防止简单的警报通知

问题描述 投票:14回答:3

我自己的应用程序使用与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) } 

现在,谷歌自己的实施显然已被打破 - 即使我不想做任何繁重的背景工作,我也不能再使用这种技术了。但是,我应该如何在非常具体的时间点唤醒用户呢? (想想我的应用程序作为闹钟)

alarmmanager android-notifications wakeup android-8.0-oreo
3个回答
9
投票

我的问题的答案简单明了:

而不是使用服务来显示通知(就像谷歌在其IO计划应用程序中所做的那样!),使用BroadcastReceiver!

我不知道为什么Google确实使用了IntentService,但现在在Android O上,由于后台执行限制,这根本不再起作用了。

尽管BroadcastReceiver显然仍然可以运行一小段时间并显示通知。

如果有人可以告诉我为什么谷歌首先使用IntentService,那么奖励积分......这花了我很多时间才弄明白,因为我认为谷歌知道他们在做什么...... :(


7
投票

但是,我应该如何在非常具体的时间点唤醒用户呢? (想想我的应用程序作为闹钟)

首先,您的代码不准确。如果设备处于打盹模式,我预计最多+/- 10分钟。如果您想要精确的计时,并且您的应用程序确实是一个闹钟,请使用setAlarmClock()

对于您现有的代码,use getForegroundService()而不是API Level 26+上的getService()


0
投票

您甚至可以考虑定期运行SyncAdapter / Job Scheduler来执行相同的业务逻辑。要设置新的定期同步,您可以首次在Application Launch Itself上进行。

© www.soinside.com 2019 - 2024. All rights reserved.