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

手机复位后AlarmManager报警不触发

BroadcastReciever 不工作或 AlarmManager 未设置

意图不将数据传递给 AlarmManager 的 BroadcastReceiver