我与AlarmManager.setExact()挣扎了几天。我的应用程序需要准确的警报,并且可以通过AlarmManager.setRepeating()在较旧的Android上正常运行。
我了解到自API 19以来它已经发生了变化,并相应地更新了我的代码。
这是负责设置警报的代码:
PendingIntent pi = PendingIntent.getBroadcast(context.getApplicationContext(), alarmOrder+1, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getAlarmManager(context).setExact(AlarmManager.RTC_WAKEUP, alarmTimeMillis, pi);
}
else {
getAlarmManager(context).setRepeating(AlarmManager.RTC_WAKEUP, alarmTimeMillis, AlarmManager.INTERVAL_DAY, pi);
}
广播接收器通过警报屏幕开始新的活动:
@Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AlarmTimeReceiver");
wl.acquire();
Intent alarmIntent = new Intent(context, AlarmActivity.class);
alarmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
context.startActivity(alarmIntent);
//Release the lock
wl.release();
}
事实是,在通过USB电缆连接的Android 4.4设备上进行测试时,一切正常。闹钟始终在指定的时间开始(打开/关闭屏幕)。不幸的是,当我断开设备与计算机的连接时,只有在打开屏幕时,警报才能正确启动。当我关闭屏幕时,警报会在不准确的时间开始。
我错过了什么吗?你们中有人遇到过类似情况吗?
最佳答案
它可以在Android
并不是的。_WAKEUP
警报通过框架管理的WakeLock
保证设备保持唤醒状态,直到onReceive()
返回。然后,框架释放WakeLock
,如果没有其他未完成的WakeLocks
,则设备可以重新进入睡眠状态。
按照书面形式,您的WakeLock
是毫无意义的。它仅复制框架管理的WakeLock
而不增加价值。startActivity()
是异步的。在onReceive()
结束并发布框架管理的WakeLock
(和您的附加框架)时,活动将不会开始。现在,有时,您的活动无论如何都会有机会开始,因为该设备无法快速入睡。我假设您在活动中使用了android:keepScreenOn
或等效功能,因此一旦达到这一点,就会有另一个未完成的WakeLock
,并且设备无法自动进入睡眠状态。
但是,有时设备确实会在您开始活动之前重新入睡。 Android 5.0可能已经改变了这一点-如果Android更加积极地使设备更快地进入睡眠状态,这至少不会令我感到惊讶。因此,虽然您以前的方法可能在90%的时间内都有效,但现在可能要少得多。但是,您以前的方法不能100%地起作用。
我们在服务方面也看到了同样的事情。实际上,这种情况在那里更为普遍。因此,我在2009年4月创建了the WakefulIntentService
,并在2013年8月创建了Google released WakefulBroadcastReceiver
。两者都提供了一种在WakeLock
中获取onReceive()
的模式,但是直到服务工作完成后才释放它。
这些解决方案都无法立即为您使用,因为两者都与服务紧密相关。但是,您可以将其用作提出自己的想法的来源。您需要将WakeLock
移动到静态数据成员(ick)中,并且一旦您的活动足够长且具有自己的release()
,则只需将WakeLock
移至该位置。例如,如果您正在用Java代码在setKeepScreenOn()
上调用View
,那么一旦完成,我希望可以放开原始的WakeLock
。然后,框架可以根据用户输入来接管并释放保持打开状态的WakeLock
。
关于android - 手机休眠时,Kitkat中的AlarmManager.setExact仍然不准确,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27589181/