Android重复闹钟不能正确重复

时间:2015-06-12 21:49:29

标签: android android-intent alarmmanager alarm intentservice

我有一个警报,我想每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();
    }
}

2 个答案:

答案 0 :(得分:4)

我有一个类似的问题,我需要每隔15秒就发一次服务......我做了以下事情。

  1. 我有一个扩展Application的类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;
        }
    }
    
    1. 名为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. 当服务被触发时,我得到一个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 ... 
         }
      

答案 1 :(得分:3)

我假设你在api 19或以上。警报管理员的文件说:

  

注意:从API 19(KITKAT)开始,警报传递不准确:操作系统将移动警报以最小化唤醒和电池使用。有新的API支持需要严格交付保证的应用程序;请参阅setWindow(int,long,long,PendingIntent)和setExact(int,long,PendingIntent)。 targetSdkVersion早于API 19的应用程序将继续查看之前的行为,其中所有警报都在请求时准确传递。

您尝试使用setRepeating(),但在api 19及更高版本上调用setInexactRepeating()。你19岁以上

  

setInexactRepeating():安排具有不精确触发时间要求的重复警报;例如,警报每小时重复一次,但不一定在每小时的顶部重复。

这解释了你的奇怪结果。

如果您想设置处于开始时间,则应使用setExact。不幸的是没有setExactRepating所以你必须自己创建。在执行之后安排新警报或类似事件。

在alarmmanager文档中注意:

  

注意:警报管理器适用于您希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未运行也是如此。对于正常的计时操作(刻度,超时等),使用Handler更容易,效率更高。

也许你应该看看这个。