参考:Schedule exact alarms are denied by default | Android Developers
permission:
Calendar and alarm clock apps should declare USE_EXACT_ALARM
判断是否有权限:canScheduleExactAlarms()
如果没有权限, 请求用户打开权限: action: Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM
通过接受广播判断用户是否授予该权限:
AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED
AlarmManager manager = ContextCompat.getSystemService(context, AlarmManager.class);
if (!manager.canScheduleExactAlarms()) {
IntentFilter filter = new IntentFilter(AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED);
context.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED);
context.startActivity(new Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM));
} else {
showAlarm(context, manager);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
AlarmManager manager = ContextCompat.getSystemService(context, AlarmManager.class);
if (intent.getAction().equals(AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED)) {
context.unregisterReceiver(receiver);
if (manager.canScheduleExactAlarms()) {
showAlarm(context, manager);
}
}
}
};
如果有权限, 则可以开启定时服务
Intent intent = new Intent();
intent.setAction("Alarm time");
PendingIntent pending = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_IMMUTABLE);
manager.setExact(AlarmManager.RTC, System.currentTimeMillis() + 10 * 1000, pending);
/**
* RTC
* Alarm time in System.currentTimeMillis() (wall clock time in UTC). This alarm does not wake the device up; if it goes off while the device is asleep, it will not be delivered until the next time the device wakes up.
*
*
* RTC_WAKEUP
* Alarm time in System.currentTimeMillis() (wall clock time in UTC), which will wake up the device when it goes off.
*
*
* ELAPSED_REALTIME :从启动到现在的时间
* Alarm time in SystemClock.elapsedRealtime() (time since boot, including sleep). This alarm does not wake the device up; if it goes off while the device is asleep, it will not be delivered until the next time the device wakes up.
*
*
* ELAPSED_REALTIME_WAKEUP
* Alarm time in SystemClock.elapsedRealtime() (time since boot, including sleep), which will wake up the device when it goes off.
**/
/**
* this alarm will be allowed to execute even when the system is in low-power idle modes.
*
* When the alarm is dispatched, the app will also be added to the system's temporary power exemption list
* for approximately 10 seconds to allow that application to acquire further wake locks in which to complete its work.
* there are restrictions on how frequently these alarms will go off for a particular application.
* Under normal system operation, it will not dispatch these alarms more than about every minute.
* @param context
* @param manager
*/
private void setExactAndAllowWhileIdle(Context context, AlarmManager manager) {
Intent intent = new Intent();
intent.setAction("Alarm time");
PendingIntent pending = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_IMMUTABLE);
manager.setExactAndAllowWhileIdle(AlarmManager.RTC, System.currentTimeMillis() + 10 * 1000, pending);
}
/**
* 在指定时间窗口内执行
*
* @param context
* @param manager
*/
private void setWindow(Context context, AlarmManager manager) {
Intent intent = new Intent();
intent.setAction("Alarm time");
PendingIntent pending = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_IMMUTABLE);
manager.setWindow(AlarmManager.RTC, System.currentTimeMillis() + 10 * 1000, System.currentTimeMillis() + 10 * 60 * 1000, pending);
}
private void set(Context context, AlarmManager manager) {
Intent intent = new Intent();
intent.setAction("Alarm time");
PendingIntent pending = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_IMMUTABLE);
manager.set(AlarmManager.RTC, System.currentTimeMillis() + 10 * 1000, pending);
}