Android:正确使用AlarmManager而不耗尽电池的方法

时间:2012-12-28 22:14:19

标签: android alarmmanager

我需要在我的应用程序中进行背景检查,基本上轮询各种URL以获取新内容。所以我读过这是用AlarmManager完成的。

问题是,我不需要在新内容到达时立即通知用户。假设我每小时检查一次,我在手机正在睡觉时没有做任何检查,并在手机使用时恢复检查时完全没问题。这样,用户最终会获得通知,但排放量很小。

所以我尝试过使用setInExactRepeating。我是在启动时启动它,但也是在app启动时(主要用于安装后的会话,并确保它正在运行,即使应用程序被“强制杀死”)。如何阻止所有这些检查加起来? (只有在没有运行时才运行新检查,或者需要停止前一个检查。)

2 个答案:

答案 0 :(得分:7)

我发现setInexact重复加上ELAPSED_REALTIME(或RTC)可以很好地实现极小的电池消耗。在现有的pendingintent(相同的intent和id)上使用标志FLAG_UPDATE_CURRENT将简单刷新当前的警报计划(如果已存在)。或者,添加Ralgha建议的代码以检查并查看是否已创建待处理的意图并设置警报,如果没有,则设置待处理的意图和警报计划。两种方法都可能对电池产生相同的影响(可忽略不计)。什么会造成大量的消耗,是经常安排的事情。事实上,你只想每小时更新一次,而不是在屏幕关闭时更新,你的应用程序几乎不会使用任何电池(假设它完成了它的处理相对较快并且很好地清理完毕)

http://developer.android.com/reference/android/app/AlarmManager.html#ELAPSED_REALTIME

ELAPSED_REALTIME

此警报不会唤醒设备;如果它在设备处于睡眠状态时熄灭,则在下次设备唤醒时才会发送。

http://developer.android.com/reference/android/app/AlarmManager.html#setInexactRepeating%28int,%20long,%20long,%20android.app.PendingIntent%29

setInexactRepeating

这些警报比setRepeating(int,long,long,PendingIntent)提供的严格重复更节能,因为系统可以调整警报的阶段以使它们同时触发,从而避免唤醒设备睡得太多了。

http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_UPDATE_CURRENT

FLAG_UPDATE_CURRENT

...如果描述的PendingIntent已经存在,那么保留它,但是它用这个新Intent中的内容替换它的额外数据。如果您创建只有额外内容更改的意图,并且不关心接收到您之前的PendingIntent的任何实体将能够使用您的新附加功能启动它,即使它们未明确赋予它,也可以使用此功能。

答案 1 :(得分:1)

您可以在设置之前检查警报是否已经设置,并且您还可以使用标志,以便在设备唤醒之前不会发出警报。

if ( PendingIntent.getBroadcast( context, 0, updateIntent, PendingIntent.FLAG_NO_CREATE ) == null )
{
    pendingIntent = PendingIntent.getBroadcast( context, 0, updateIntent, 0 );
    getSystemService( ALARM_SERVICE ).setInexactRepeating( AlarmManager.RTC, System.currentTimeMillis(), AlarmManager.INTERVAL_HOUR, pendingIntent );
}