AlarmManager的行为不一致(警报多次触发,或根本不触发)

时间:2019-07-09 19:51:27

标签: java android alarmmanager

我有一个按钮,使用AlarmManager.setRepeating设置警报,另一个按钮将其删除,每次设置警报时,都会迭代PendingIntent中的requestCode,以免将其与已设置和取消的请求混淆。 (该应用将来会同时设置多个警报)。当我设置警报(setRepeating)时,有时会按预期工作,有时会比在2-3分钟后响起的时间快得多地触发两次(我将在3-5分钟后设置警报供我测试)。

还请注意:我已插入设备,并且屏幕设置为保持唤醒状态,在测试过程中,应用程序通常始终处于前景状态,有时我将其置于背景或旋转屏幕(通常是错误的)。

我已经尝试过setExact(),但是我不介意它在0-5分钟后关闭,但是我确实需要它关闭并且不再重复。

我一直将初始时间设置为我希望它在小时和分钟开始的前一天开始运行,同样的事情又回到了十天,又有了一百个(只是看会发生什么)类似的结果

我正在使用Joda DateTime获取setRepeating方法的警报时间的毫秒数,并使用AlarmManager.INTERVAL_DAY设置下一个警报的间隔(我的警报需要每24小时关闭一次)

requestCode是一个常量int,我在测试过程中对其进行递增和跟踪。 我从活动的getBaseContext()获取的上下文

我设置警报的代码:


        Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
        intent.putExtra(ALARMS_INDEX_KEY,requestCode);
        PendingIntent sender = PendingIntent.getBroadcast(context, requestCode, intent, 0);
        AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);//After after 5 seconds
        addAlarmIndex(context, requestCode);
        //test: DateTime.now().minusDays(10).withTimeAtStartOfDay()
        DateTime set_for = DateTime.now().withTimeAtStartOfDay().withHourOfDay(14).
                withMinuteOfHour(34).withSecondOfMinute(0).
                withMillisOfSecond(0);


        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, set_for.getMillis(), AlarmManager.INTERVAL_DAY , sender);

我要取消警报的代码:


            Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
            PendingIntent sender = PendingIntent.getBroadcast(context, requestCode, intent, 0);
            AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            alarmManager.cancel(sender);

我在AlarmManagerBroadcastReceiver中的代码扩展了BroadcastReceiver


    @Override
    public void onReceive(Context context, Intent intent) {
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "test_alarm:");
        wl.acquire();


        int alarm_index = -1;
        if(intent.hasExtra(ALARMS_INDEX_KEY)){
            alarm_index = intent.getIntExtra(ALARMS_INDEX_KEY,-1);
        }
        Log.i("medic_debug_timertest","Alarm !!!, fired @: "+DateTime.now().toString("YYYY/MM/dd @ HH:mm:ss") + " alarm_index: " + requestCode);


        wl.release();
    }

我期望的是,在应关闭的时间之前设置警报,而不是在应设置的时间(在几分钟内)关闭警报

发生的事情是有时它根本没有响起(也许我将闹钟设置为在我设置时响起),这可能不是问题,但有时它在我设置好后不久就响了,它会在1-2分钟后的0-1秒内熄灭两次,然后会在设置的正确时间再次熄灭。

根据我到目前为止的观察,它始终是以下三种情况之一: 在正确的时间熄灭。 一点也不熄灭。 熄灭三下,立即两次(在预定时间之前1-2分钟),然后在正确的时间第三次熄灭。

我在做什么错?我如何才能在大约正确的时间使警报响起一次

更新:

好吧...首先,我更改了设置计时器的行,方法是:

        DateTime set_for = DateTime.now().minusDays(10).withTimeAtStartOfDay().withHourOfDay(14).
                withMinuteOfHour(34).withSecondOfMinute(0).
                withMillisOfSecond(0);

        DateTime set_for = DateTime.now().plusMinutes(5).withSecondOfMinute(0).withMillisOfSecond(0);

以便它会在我设置它的5分钟后自动关闭,并且我可以进行多次测试而无需重新运行该应用程序。我担心在设置警报时将警报设置为关闭。

需要记住的是,AlarmManager将警报聚集在一起并在它们靠近时同时触发它们(使用setRepeating方法而不是setExact),这是为了节省电池并且不会每隔一两分钟就唤醒电话。

我使用上面的代码进行了测试,并且开始更加正常地工作。每隔1分钟设置4个警报,当第三个警报响起时,其中3个警报在同一时间发出(这是正确的行为,因为它们合计成一个以节省电池电量),最后一个警报发出得很晚应该在预期的3-5分钟后(很好,没问题)。

所以问题可能出在我取消警报并启动新警报之后,AlarmManager变得困惑(当我之前设置警报时,要在我设置警报时关闭)并尝试将已取消警报和一只应该熄灭,使未被取消的一只熄灭两次?听起来很奇怪,但也许Alarm有点bug了???

1 个答案:

答案 0 :(得分:0)

好吧,我不是100%知道为什么闹钟会触发一次相同的三遍,但是当我给闹钟运行更多时间(比如说未来5分钟到3分钟)时,给了我更多时间解决很多问题。现在因为没有给它更多的时间而感到有点傻,但是每次测试需要5分钟才能运行,等待很多,这很烦人,但现在效果更好。

帖子中的

setRepeating() of AlarmManager repeats after 1 minute no matter what the time is set (5 seconds in this case, API 18+)

它被提及: “从我认为Android 5.1(API版本22)开始,至少有1分钟的时间可以重复发送警报,并且以后不能将警报设置为少于5秒”

我肯定在那个时间范围内(或者不在那个时间范围内,而是超过5秒),但是将来进一步增加警报设置可以解决我的问题。

更新:在测试期间,我将初始计时器时间设置为过去几天,即使没有设置计时器,它也会通过间隔时间触发通知,即使没有设置计时器也是如此从设置时间开始,即使实际上不是在该时间或之前设置警报,所以这就是为什么我收到这些额外的通知的原因,我假设可以发送2个警报(具有相同的requestCode)这样关闭。