Android重复报警未正确重复

Android重复报警未正确重复,android,android-intent,alarmmanager,alarm,intentservice,Android,Android Intent,Alarmmanager,Alarm,Intentservice,我有一个闹钟,我想每5分钟重复一次。出于测试目的,我将其设置为每5秒重复一次,如下所示: AlarmManager alarmManager = (AlarmManager)getActivity().getSystemService(getActivity().ALARM_SERVICE); Intent intent = new Intent(getActivity(), CoordinateAlarmReceiver.class); PendingInten

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

我假设您使用的是api 19或更高版本。alarmmanager文档说明:

注意:从API 19(KITKAT)开始,警报传递是不精确的:操作系统将切换警报,以尽量减少唤醒和电池使用。有新的API支持需要严格交付保证的应用程序;请参见设置窗口(int,long,long,pendingent)和设置精确窗口(int,long,pendingent)。targetSdkVersion早于API 19的应用程序将继续看到之前的行为,其中所有警报都会在请求时准确传递

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

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

这就解释了你奇怪的结果

如果要在excat时间设置is,应使用
setExact
。不幸的是,没有
设置ExactRepating
,所以您必须自己创建它。在一个警报执行后安排一个新的警报或类似的事件

alarmmanager文档中的注意事项:

注意:Alarm Manager适用于希望在特定时间运行应用程序代码的情况,即使应用程序当前未运行。对于正常的计时操作(滴答声、超时等),它更容易使用,效率更高


也许您应该看看这个。

我假设您使用的是api 19或更高版本。alarmmanager文档说明:

注意:从API 19(KITKAT)开始,警报传递是不精确的:操作系统将切换警报,以尽量减少唤醒和电池使用。有新的API支持需要严格交付保证的应用程序;请参见设置窗口(int,long,long,pendingent)和设置精确窗口(int,long,pendingent)。targetSdkVersion早于API 19的应用程序将继续看到之前的行为,其中所有警报都会在请求时准确传递

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

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

这就解释了你奇怪的结果

如果要在excat时间设置is,应使用
setExact
。不幸的是,没有
设置ExactRepating
,所以您必须自己创建它。在一个警报执行后安排一个新的警报或类似的事件

alarmmanager文档中的注意事项:

注意:Alarm Manager适用于希望在特定时间运行应用程序代码的情况,即使应用程序当前未运行。对于正常的计时操作(滴答声、超时等),它更容易使用,效率更高


也许你应该看看这个。

我有一个类似的问题,我需要每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 ... 
       }
    

  • 我有一个类似的问题,我需要每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 ... 
       }
    

  • setRepeating的行为类似于kitkat和更新设备上的setInexactRepeating,iirc。setRepeating的行为类似于kitkat和更新设备上的setInexactRepeating,iirc。