17

我自己的应用程序使用的技术与 2016 年的 Google I/O 应用程序显示的完全相同。查看源代码

我需要在一个非常具体的时间点提醒用户——使用通知。

为此,我使用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) } 

现在,谷歌自己的实现显然被破坏了——即使我不想做任何繁重的后台工作,我也不能再使用这种技术了。但是我应该如何在一个非常特定的时间点唤醒用户呢?(把我的应用想象成一个闹钟)

4

3 回答 3

13

我的问题的答案很简单:

不要使用服务来显示通知(就像 Google 在其 IO Schedule 应用程序中所做的那样!),使用 BroadcastReceiver!

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

BroadcastReceiver 虽然显然仍然可以运行片刻并显示通知。

如果有人能告诉我为什么谷歌首先使用 IntentService 会加分......这花了我很长时间才弄清楚,因为我认为谷歌知道他们在做什么...... :(

于 2018-01-02T23:07:08.823 回答
8

但是我应该如何在一个非常特定的时间点唤醒用户呢?(把我的应用想象成一个闹钟)

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

对于您现有的代码,使用getForegroundService()而不是getService()API 级别 26+。

于 2017-07-11T10:22:42.940 回答
0

您甚至可以考虑定期运行 SyncAdapter/Job Scheduler 以执行相同的业务逻辑。并设置一个新的定期同步,您可以首次在应用程序启动本身上进行。

于 2017-12-12T11:13:05.980 回答