Android 6.0 Doze模式下的Alarm Manager问题

时间:2016-02-25 13:54:05

标签: android alarmmanager android-pendingintent android-alarms android-doze-and-standby

我制作的应用程序一直有效,直到Android 6.0。我认为这是Doze功能,它不允许我的警报发射。

我使用sharedpreferences来处理选项:

//ENABLE NIGHT MODE TIMER
    int sHour = blockerTimerPreferences.getInt("sHour", 00);
    int sMinute = blockerTimerPreferences.getInt("sMinute", 00);

    Calendar sTime = Calendar.getInstance();
    sTime.set(Calendar.HOUR_OF_DAY, sHour);
    sTime.set(Calendar.MINUTE, sMinute);

    Intent enableTimer = new Intent(context, CallReceiver.class);
    enableTimer.putExtra("activate", true);
    PendingIntent startingTimer = PendingIntent.getBroadcast(context, 11002233, enableTimer, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager sAlarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    sAlarm.setRepeating(AlarmManager.RTC_WAKEUP,
            sTime.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, startingTimer);

这里有什么错误吗?

这是一个阻止通话的应用。谢谢!

修改 我有3个文件(更多但是......),如:

MainActivity (All code)
CallReceiver (Broadcast that triggers the alarm again (reboot etc))
CallReceiverService (Handles the call / phone state)

2 个答案:

答案 0 :(得分:14)

打盹模式会将您的闹钟延迟到下一个维护窗口。为避免Doze mode阻止您的闹钟,您可以使用setAndAllowWhileIdle()setExactAndAllowWhileIdle()setAlarmClock()。您将有大约10秒来执行您的代码,并设置您的下一个警报(对于_AndAllowWhileIdle的方法,每15分钟不超过一次

如果您想测试打盹模式,可以使用ADB command

  
      
  1. 使用Android 6.0(API级别23)或更高版本的系统映像配置硬件设备或虚拟设备。

  2.   
  3. 将设备连接到您的开发计算机并安装您的应用程序。

  4.   
  5. 运行您的应用并将其保持活动状态。
  6.   
  7. 关闭设备屏幕。 (该应用程序仍然有效。)   通过运行以下命令强制系统循环通过打盹模式:

         

    adb shell dumpsys battery unplug

         

    adb shell dumpsys deviceidle step

  8.   
  9. 您可能需要多次运行第二个命令。重复此操作,直到设备状态变为空闲状态。

  10.   
  11. 重新启动设备后,请观察应用的行为。当设备退出打盹时,请确保应用程序正常恢复。
  12.   

编辑:添加setAlarmClock示例

请勿忘记检查SDK级别(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP

AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarmReceiver.class); //or just new Intent() for implicit intent 
//set action to know this come from the alarm clock
intent.setAction("from.alarm.clock");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//Alarm fire in 5s.
am.setAlarmClock(new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + 5000, pi), pi);

答案 1 :(得分:1)

如果设备处于打盹模式,则需要使用以下API之一: setExactAndAllowWhileIdlesetAndAllowWhileIdle

请注意,在打盹模式下,对于重复警报,没有用于唤醒设备的API,因此如果您在打盹时需要重复警报来唤醒设备,则必须使用上面的API并重新启动计时器每次发生时都会计时。