使用setExactAndAllowWhileIdle方法

时间:2017-06-29 10:24:39

标签: android service background alarmmanager wakeup

我需要每60秒唤醒一次服务(例如)。

服务将自身配置为使用以下代码唤醒:

private void rescheduleService() {

    // setup calendar
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(new Date());
    calendar.add(Calendar.SECOND, 60);

    // setup intent
    Intent serviceGeofence = new Intent(this, ServiceGeofence.class); // this service
    PendingIntent pendingIntent = PendingIntent.getService(this, 0, serviceGeofence, PendingIntent.FLAG_CANCEL_CURRENT);

    // setup alarm
    AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    if(Build.VERSION.SDK_INT >= 23) {
        alarmManager.setExactAndAllowWhileIdle(
                AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(),
                pendingIntent);
    } else if(Build.VERSION.SDK_INT >= 19){
        alarmManager.setExact(
                AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(),
                pendingIntent);
    } else {
        alarmManager.set(
                AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(),
                pendingIntent);
    }

    Log.i(TAG, "next alarm: " + calendar.toString());
    Log.i(TAG, "alarm configured");

}

上述代码在手机充电或通过USB连接时工作正常。它按预期每60秒执行一次。我能够在LogCat中看到它。

但是,当我从USB上拔下手机时,服务会随机唤醒(3或5分钟,甚至30分钟后)。

我使用setExactAndAllowWhileIdlesetExact(取决于Android版本)等方法在我配置它时严格唤醒设备。但它仅在设备连接到USB时有效。

TL; DR;使用上面的代码:

  • 当设备连接到USB时:工作正常。
  • 当设备与USB断开连接时:无法按预期工作。

知道发生了什么事吗?

1 个答案:

答案 0 :(得分:-1)

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

基本上......如果sdk> = 19,你需要使用serExact。不要使用setExactAndAllowWhileIdle