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重复警报未正确重复的主要内容,如果未能解决你的问题,请参考以下文章

Android - 空闲时允许重复警报

在Android警报管理器中设置时间-立即触发警报[重复]

android重复警报,应按月重复,每个月在同一天重复,依此类推

如何在 Android 中停止重复警报服务?

android定期重复警报不起作用

Android简单的警报对话框[重复]