Android重复警报未正确重复
Posted
技术标签:
【中文标题】Android重复警报未正确重复【英文标题】:Android repeating alarm not repeating correctly 【发布时间】:2015-06-12 21:49:28 【问题描述】:我想每 5 分钟左右重复一次闹钟。出于测试目的,我将其设置为每 5 秒重复一次,如下所示:
AlarmManager alarmManager = (AlarmManager)getActivity().getSystemService(getActivity().ALARM_SERVICE);
Intent intent = new Intent(getActivity(), CoordinateAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getService(getActivity(), 1, intent, 0);
int repeatSeconds = 5;
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
repeatSeconds * 1000, pendingIntent);
并且接收方IntentService在收到告警时会打印一条日志语句。但是,它每分半钟触发一次,而不是每 5 秒触发一次,它在哪里设置不正确?我也尝试过使用 setRepeating() 而不是 setInexactRepeating() 但我得到了相同的结果。
这是我的闹钟接收器:
public class CoordinateAlarmReceiver extends IntentService
public CoordinateAlarmReceiver()
super("CoordinateAlarmReceiver");
/*
Alarm received, get new contacts which then shows notification
*/
@Override
protected void onHandleIntent(Intent intent)
MyLog.i("coordinate alarm received");
//new GetNewContactsTask(this).execute();
【问题讨论】:
setRepeating 在 kitkat 和更新的设备 iirc 上的行为类似于 setInexactRepeating。 【参考方案1】:我假设您使用的是 api 19 或更高版本。警报管理器文档说:
注意:从 API 19 (KITKAT) 开始,警报传递是不准确的:操作系统将切换警报以最大程度地减少唤醒和电池使用。有新的 API 来支持需要严格交付保证的应用程序;参见 setWindow(int, long, long, PendingIntent) 和 setExact(int, long, PendingIntent)。 targetSdkVersion 早于 API 19 的应用程序将继续看到以前的行为,即所有警报都在请求时准确传递。
您尝试使用 setRepeating()
,但在 api 19 及更高版本上调用 setInexactRepeating()
。 19岁及以上的你
setInexactRepeating():安排一个具有不精确触发时间要求的重复警报;例如,每小时重复一次的警报,但不一定在每小时的开头。
这解释了你奇怪的结果。
如果你想设置在excat时间,你应该使用setExact
。不幸的是没有setExactRepating
,所以你必须自己创建它。在执行或类似的事情后安排一个新的警报。
alarmmanager 文档中的注释:
注意:警报管理器适用于您希望应用程序代码在特定时间运行的情况,即使您的应用程序当前未运行。对于正常的计时操作(滴答声、超时等),使用Handler 会更容易且效率更高。
也许你应该看看这个。
【讨论】:
【参考方案2】:我有一个类似的问题,我需要每 15 秒触发一次服务......我做了以下事情。
我有一个扩展应用程序的类,称为 MyApplication。此类包含一个警报管理器的实例。
public class MyApplication extends Application
private MyAlarmManager alarmMgr;
@Override
public void onCreate()
Log.d(TAG, "MyApplication onCreate");
super.onCreate();
Log.d(TAG, "initing alarmMgr ...");
alarmMgr = new MyAlarmManager(this);
public MyAlarmManager getAlarmManager()
return alarmMgr;
名为 MyAlarmManager 的 AlarmManager 创建、启动和停止警报 现在 为该服务设置下一个警报。
public class MyAlarmManager
private MyApplication mApp;
private Intent intent;
private PendingIntent pendingIntent;
private AlarmManager alarmMgr;
private static final long FREQUENCY = 15000;
public MyAlarmManager(Context context)
mApp = (MyApplication) context;
// android alarm service
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// service to be fired every 15 seconds
intent = new Intent(context, MyService.class);
pendingIntent = PendingIntent.getService(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
setNextAlarm();
public void setNextAlarm()
Log.d(TAG, "setting next alarm...");
alarmMgr.set(AlarmManager.RTC_WAKEUP, (System.currentTimeMillis() + FREQUENCY), pendingIntent);
private void stopAlarms()
Log.d(TAG, "stopping Alarms");
alarmMgr.cancel(pendingIntent);
当服务被触发时,我得到一个 MyApplication 的实例,获取 AlarmManager 并安排下一个警报。
public class MyService extends Service
MyApplication mApp;
@Override
public int onStartCommand(Intent intent, int flags, int startId)
Log.d(TAG, "in onStartCommand");
// init the app reference if needed
if (mApp == null)
Log.d(TAG, "app was null. Creating now...");
mApp = (MyApplication) getApplicationContext();
// schedule the next zone check
mApp.getAlarmMgr().setNextAlarm();
// custom functionality ...
【讨论】:
以上是关于Android重复警报未正确重复的主要内容,如果未能解决你的问题,请参考以下文章