我希望我的闹钟(Android AlarmManager)每N秒重复一次。
我使用了一些类:
AlarmReceiver (接收警报意图并使用AlarmHandler类重复它们);
public class AlarmReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
AlarmHandler.repeatAlarm(context, intent);
completeWakefulIntent(intent);
}
}
AlarmHandler (设置,取消和重复闹钟);
public class AlarmHandler {
public static void setAlarm(Context context, String intentName, int delay, long beginTime, long endTime) {
if(endTime<beginTime) {
return;
}
Intent alarmIntent = new Intent(intentName);
alarmIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
alarmIntent.putExtra("Delay", delay);
alarmIntent.putExtra("EndTime", endTime);
PendingIntent pendingAlarmIntent = PendingIntent.getBroadcast(context.getApplicationContext(), 0,
alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmService = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if(PendingIntent.getBroadcast(context.getApplicationContext(), 0, alarmIntent, PendingIntent.FLAG_NO_CREATE) != null) {
alarmService.cancel(pendingAlarmIntent);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmService.setExactAndAllowWhileIdle(android.app.AlarmManager.RTC_WAKEUP,
beginTime,
pendingAlarmIntent);
}
else {
alarmService.setExact(android.app.AlarmManager.RTC_WAKEUP,
beginTime,
pendingAlarmIntent);
}
}
public static void setAlarm(Context context, String intentName, int delay) {
setAlarm(context, intentName, delay, System.currentTimeMillis()+delay, Long.MAX_VALUE);
}
public static void repeatAlarm(Context context, Intent intent) {
PendingIntent pendingAlarmIntent = PendingIntent.getBroadcast(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmService = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if(PendingIntent.getBroadcast(context.getApplicationContext(), 0, intent, PendingIntent.FLAG_NO_CREATE) != null) {
alarmService.cancel(pendingAlarmIntent);
}
int intentDelay = intent.getIntExtra("Delay", 0);
long intentEndTime = intent.getLongExtra("EndTime", Long.MAX_VALUE),
alarmTime = System.currentTimeMillis()+intentDelay;
if(intentDelay > 0 && alarmTime<intentEndTime) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmService.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
alarmTime, pendingAlarmIntent);
}
else {
alarmService.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pendingAlarmIntent);
}
}
}
public static void cancelAlarm(Context context, String intentName) {
Intent alarmIntent = new Intent(intentName);
PendingIntent pendingAlarmIntent = PendingIntent.getBroadcast(context.getApplicationContext(), 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingAlarmIntent);
pendingAlarmIntent.cancel();
}
}
某些特定类从Android AlarmManager接收自定义Intents(例如, com.lukanin.testappjava2.BLUETOOTH_INTERVAL );
public class fakeReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
completeWakefulIntent(intent);
}
}
我的 Manifest (AndroidManifest.xml)文件如下所示:
<receiver android:name=".fakeReceiver"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="com.lukanin.testappjava2.BLUETOOTH_INTERVAL" />
</intent-filter>
</receiver>
<receiver android:name=".Alarm.AlarmReceiver"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="com.lukanin.testappjava2.BLUETOOTH_INTERVAL" />
</intent-filter>
</receiver>
那么问题是什么?首先,我将主要活动的Android AlarmManager设置为:
AlarmHandler.setAlarm(context, "com.lukanin.testappjava2.BLUETOOTH_INTERVAL", 1000 * 30 * 1);
Logcat输出:
10-14 14:35:00.924 32451-32451/com.lukanin.testappjava2 I/(ALARM): SETTING NEW ALARM
10-14 14:35:00.924 32451-32451/com.lukanin.testappjava2 I/(ALARM): INTENT NAME: com.lukanin.testappjava2.BLUETOOTH_INTERVAL
10-14 14:35:00.924 32451-32451/com.lukanin.testappjava2 I/(ALARM): DELAY: 30000
10-14 14:35:00.925 32451-32451/com.lukanin.testappjava2 I/(ALARM): BEGIN TIME: 1476444930924
10-14 14:35:00.925 32451-32451/com.lukanin.testappjava2 I/(ALARM): END TIME: 9223372036854775807
然后我只用 fakeReceiver 接收 com.lukanin.testappjava2.BLUETOOTH_INTERVAL Intent一次,用 AlarmReceiver 接收次数。我究竟做错了什么?这些接收器完全相同!
Logcat输出:
10-14 14:35:06.491 32451-32451/com.lukanin.testappjava2 I/(ALARM): ALARM RECEIVER
10-14 14:35:06.491 32451-32451/com.lukanin.testappjava2 I/(ALARM): REPEATING EXISTING ALARM
10-14 14:35:06.491 32451-32451/com.lukanin.testappjava2 I/(ALARM): INTENT NAME: com.lukanin.testappjava2.BLUETOOTH_INTERVAL
10-14 14:35:06.491 32451-32451/com.lukanin.testappjava2 I/(ALARM): CONTEXT: android.app.ReceiverRestrictedContext@4432f21
10-14 14:35:25.694 32451-32451/com.lukanin.testappjava2 I/(ALARM): ALARM RECEIVER
10-14 14:35:25.694 32451-32451/com.lukanin.testappjava2 I/(ALARM): REPEATING EXISTING ALARM
10-14 14:35:25.694 32451-32451/com.lukanin.testappjava2 I/(ALARM): INTENT NAME: com.lukanin.testappjava2.GPS_INTERVAL
10-14 14:35:25.694 32451-32451/com.lukanin.testappjava2 I/(ALARM): CONTEXT: android.app.ReceiverRestrictedContext@4432f21
10-14 14:35:30.932 32451-32451/com.lukanin.testappjava2 I/FAKE: FAKE RECEIVER
10-14 14:35:30.946 32451-32451/com.lukanin.testappjava2 I/(ALARM): ALARM RECEIVER
10-14 14:35:30.946 32451-32451/com.lukanin.testappjava2 I/(ALARM): REPEATING EXISTING ALARM
10-14 14:35:30.946 32451-32451/com.lukanin.testappjava2 I/(ALARM): INTENT NAME: com.lukanin.testappjava2.BLUETOOTH_INTERVAL
10-14 14:35:30.946 32451-32451/com.lukanin.testappjava2 I/(ALARM): CONTEXT: android.app.ReceiverRestrictedContext@4432f21
10-14 14:35:55.712 32451-32451/com.lukanin.testappjava2 I/(ALARM): ALARM RECEIVER
10-14 14:35:55.712 32451-32451/com.lukanin.testappjava2 I/(ALARM): REPEATING EXISTING ALARM
10-14 14:35:55.712 32451-32451/com.lukanin.testappjava2 I/(ALARM): INTENT NAME: com.lukanin.testappjava2.GPS_INTERVAL
10-14 14:35:55.712 32451-32451/com.lukanin.testappjava2 I/(ALARM): CONTEXT: android.app.ReceiverRestrictedContext@4432f21
10-14 14:36:00.975 32451-32451/com.lukanin.testappjava2 I/(ALARM): ALARM RECEIVER
10-14 14:36:00.975 32451-32451/com.lukanin.testappjava2 I/(ALARM): REPEATING EXISTING ALARM
10-14 14:36:00.975 32451-32451/com.lukanin.testappjava2 I/(ALARM): INTENT NAME: com.lukanin.testappjava2.BLUETOOTH_INTERVAL
10-14 14:36:00.975 32451-32451/com.lukanin.testappjava2 I/(ALARM): CONTEXT: android.app.ReceiverRestrictedContext@4432f21