AlarmManager 不调用 BroadcastReceiver
Posted
技术标签:
【中文标题】AlarmManager 不调用 BroadcastReceiver【英文标题】:AlarmManager does not call BroadcastReceiver 【发布时间】:2019-05-09 09:53:53 【问题描述】:我在每天的特定时间创建了一个预定的重复警报,使用 AlarmManager 在扩展 BroadcastReceiver 的类中触发通知。但是从设置了 AlarmManager 的活动中永远不会调用 onReceive 方法。
我正在使用 android Oreo 来测试应用程序,因此我创建了一个方法 createNotificationChannel() 来设置 NotificationChannel 并从我的 MainActivity onCreate() 方法中调用它。
public void createNotificationChannel()
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >=
android.os.Build.VERSION_CODES.O)
// Create the NotificationChannel with all the parameters.
NotificationChannel notificationChannel = new NotificationChannel
(PRIMARY_CHANNEL_ID,
"My Notification",
NotificationManager.IMPORTANCE_HIGH);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setDescription
("My Notification Description");
mNotificationManager.createNotificationChannel(notificationChannel);
带有一些变量:
private NotificationManager mNotificationManager;
private static final int NOTIFICATION_ID = 0;
private static final String PRIMARY_CHANNEL_ID =
"primary_notification_channel";
然后我设置了一个按钮,onClick() 方法调用 startAlarm() 方法如下:
public void startAlarm(int aHour, int aMinutes)
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent notifyIntent = new Intent(getApplicationContext(), AlarmReceiver.class);
PendingIntent notifyPendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar= Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,aHour);
calendar.set(Calendar.MINUTE, aMinutes);
alarmManager.setInexactRepeating
(AlarmManager.ELAPSED_REALTIME_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, notifyPendingIntent);
最后在 AlarmReceiver.java 类中,在 onReceive() 中如下:
public void onReceive(Context context, Intent intent)
mNotificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
callNotification(context);
private void callNotification(Context context)
Intent contentIntent = new Intent(context, DRSetting.class);
PendingIntent contentPendingIntent = PendingIntent.getActivity
(context, NOTIFICATION_ID, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, PRIMARY_CHANNEL_ID);
builder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.icon_mynotif)
.setContentTitle("My Title")
.setContentIntent(contentPendingIntent)
.setContentText("Reminder for you!")
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND)
.setContentInfo("Info");
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
在 AndroidManifest.xml 中,我放了这个:
<receiver
android:name=".AlarmReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.NOTIFY" />
</intent-filter>
</receiver>
权限如下:
<uses-permission android:name="android.permission.SET_ALARM" />
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
所以,有人可以帮助我吗,因为我找不到为什么永远不会调用 onReceive() 方法的问题,因此在 callNotification() 中没有触发任何通知。
【问题讨论】:
【参考方案1】:感谢 JournalDev,我发现导致警报不会触发的问题。这是因为从 Android Oreo 开始,隐式广播接收器在 AndroidManifest.xml 中注册时将不起作用。 相反,我们应该使用显式广播接收器。因此,我重新编写了代码,添加了两个额外的方法,如下所示:
@Override
protected void onResume()
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction("android.app.action.NEXT_ALARM_CLOCK_CHANGED");
registerReceiver(alarmReceiver, filter);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(NOTIFICATION_ID);
@Override
protected void onStop()
super.onStop();
unregisterReceiver(alarmReceiver);
另外,我们应该注意日历月份的值设置,如果我们想设置特定的日期来触发警报。 Java 中的月份是从 0 到 11 开始的,所以我们在从 DatePicker 转换月份值时需要 -1。我希望这个答案可以帮助其他面临同样问题的人。
【讨论】:
以上是关于AlarmManager 不调用 BroadcastReceiver的主要内容,如果未能解决你的问题,请参考以下文章
AlarmManager首先开火一次然后每秒反复点火......为什么?
多次调用 AlarmManager.setRepeating 提供相同的 Intent/PendingIntent 额外值,但我提供了不同的值
如何将 AlarmManager 附加到 BootReceiver