简体   繁体   English

Android重复警报未正确重复

[英]Android repeating alarm not repeating correctly

I have an alarm that I am wanting to repeat around every 5 minutes. 我有一个警报,希望每5分钟重复一次。 For testing purposes, I have it set to repeat once every 5 seconds instead, as such: 为了进行测试,我将其设置为每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);

And the receiving IntentService prints a log statement when it receives the alarm. 并且接收方IntentService在收到警报时会打印一条日志语句。 However, it fires around once every minute and a half instead of once every 5 seconds, where is it set incorrectly? 但是,它每分钟半开火一次,而不是每5秒一次开火,它在哪里设置不正确? I have also tried using setRepeating() instead of setInexactRepeating() but I get the same results. 我也尝试过使用setRepeating()代替setInexactRepeating(),但得到的结果相同。

Here is my alarm receiver: 这是我的警报接收器:

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();
    }
}

I had a similar problem in which I needed a Service fired every 15 seconds... I did the following. 我遇到了类似的问题,我需要每15秒触发一次服务……我做了以下工作。

  1. I have a class that extends Application called MyApplication. 我有一个扩展应用程序的类,称为MyApplication。 This class holds an instance of an alarm manager. 此类包含警报管理器的实例。

     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; } } 
    1. An AlarmManager called MyAlarmManager creates, starts & stops the alarms AND NOW sets the next alarm for this one service. 一个名为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); } } 
    2. When the Service is fired I get an instance of MyApplication, get the AlarmManager and schedule the next alarm. 当服务被触发时,我得到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 ... } 

I assume you are on api 19 or above. 我假设您使用的是api 19或更高版本。 The alarmmanager documentations says: 警报管理器文档说:

Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. 注意:从API 19(KITKAT)开始,警报传递是不准确的:操作系统将转移警报,以最大程度地减少唤醒和电池消耗。 There are new APIs to support applications which need strict delivery guarantees; 有一些新的API支持需要严格交付保证的应用程序。 see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). 请参见setWindow(int,long,long,PendingIntent)和setExact(int,long,PendingIntent)。 Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested. targetSdkVersion早于API 19的应用程序将继续看到以前的行为,在该行为中,所有警报均在请求时准确传递。

You tried using setRepeating() but on api 19 and above this calls setInexactRepeating() . 您尝试使用setRepeating()但在api 19及更高版本上调用了setInexactRepeating() On 19 and above you 在19岁及以上

setInexactRepeating(): Schedule a repeating alarm that has inexact trigger time requirements; setInexactRepeating():安排具有不精确触发时间要求的重复警报; for example, an alarm that repeats every hour, but not necessarily at the top of every hour. 例如,闹钟每小时重复一次,但不一定每小时重复一次。

This explains your weird result. 这解释了您的怪异结果。

If you want to set is at a excat time, you should use setExact . 如果要设置为在执行时间,则应使用setExact Unfortunalety there is no setExactRepating so you have to create this yourself. 不幸的是,没有setExactRepating因此您必须自己创建它。 Schedule a new alarm after one executes or something like that. 计划一个新的警报在执行后执行。

Note in the alarmmanager documentation: 注意在alarmmanager文档中:

Note: The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. 注意:警报管理器适用于希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未运行。 For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler . 对于正常的计时操作(滴答声,超时等),使用Handler更容易,效率更高。

Maybe you should take a look at this. 也许您应该看看这个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM