Android AlarmManager不一致性

Android AlarmManager不一致性,android,broadcastreceiver,alarmmanager,Android,Broadcastreceiver,Alarmmanager,我正在使用AlarmManager在屏幕关闭时发送广播。这在大多数设备上都可以正常工作,但在某些设备上(例如三星Galaxy S4),接收广播需要30、40甚至120秒,而不是指定的20秒。我无法访问发生这种情况的设备,因此无法检查logcat 这就是我如何设置AlarmManager的方法: AlarmManager mAlarmManager=(AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); long mInter

我正在使用
AlarmManager
在屏幕关闭时发送广播。这在大多数设备上都可以正常工作,但在某些设备上(例如三星Galaxy S4),接收广播需要30、40甚至120秒,而不是指定的20秒。我无法访问发生这种情况的设备,因此无法检查logcat

这就是我如何设置AlarmManager的方法:

AlarmManager mAlarmManager=(AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
long mInterval = 20 * 1000;
Intent i = new  Intent();
i.setAction(MY_ACTION);
mPendingIntent = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + mInterval, mPendingIntent);
这是登记在舱单上的接收人:

private class MyIntentReceiver extends BroadcastReceiver {

    private static final String TAG = "MyIntentReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(MY_ACTION)) {

            PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
            wl.acquire();

            Log.e(TAG, "onReceive");

            //Carry out my action...


            wl.release();

        }
    }

}

我将
AlarmManager.set()
方法的参数更改为
AlarmManager.Expressed\u REALTIME\u WAKEUP,SystemClock.elapsedRealtime()
,而不是我最初的
AlarmManager.RTC\u WAKEUP,System.currentTimeMillis()
,现在它也可以在S4上工作。我不知道为什么
eassed\u REALTIME\u WAKEUP
不起作用,因为它以自己的名义专门携带了
WAKEUP
,并在我测试过它的所有其他设备上工作。

的行为随着API 19的到来而改变。在阅读更新后的Javadoc之前,很多人浪费了很多时间对一个曾经运行良好的应用程序进行故障排除

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


两个问题:您在
onReceive()
中花费的时间不应超过几毫秒,并且在
onReceive()
中已经存在一个
WakeLock
。如果要将控制权传递给其他组件(例如,
//执行我的操作
实际上是委托给
IntentService
),则需要您自己的
唤醒锁
),但在您不正确的位置释放
唤醒锁
。如果您正在委托其他组件,请使用或Android支持包的
WakefulBroadcastReceiver
。谢谢,Mark。我已将代码更改为WakefulBroadcastReceiver/IntentService结构,但S4上的不一致性仍然存在(它在其他设备上也可以工作,与以前一样)。如果我增加间隔(例如,30或40秒而不是20秒),则不一致性会呈指数级增加(即,在执行操作之前,所需时间比预期时间长1-2分钟)。我对此感到困惑,因为我认为使用
RTC_WAKEUP
将确保使用实际时间,而不仅仅是“设备唤醒”时间。如果你能创建一个可复制的测试用例,把它上传到某个地方,我会看一看。我有一个S4,尽管它可能与您的S4型号不同(三星将“S4”应用于一些设备)。或者,试着根据这些症状中的一个重现你的症状。谢谢,马克,我很感激!我会试试你的样品,然后告诉你。