AlarmManager和BroadcastReceiver的LocalNotification未在Android O(oreo)中启动

笛里谁知壮士心,沙头空照征人骨。这篇文章主要讲述AlarmManager和BroadcastReceiver的LocalNotification未在Android O(oreo)中启动相关的知识,希望能为你提供帮助。
在SDK 26之前,我已经在机器人上运行了本地通知
但是在android O中我收到了以下警告,广播接收器没有被解雇。

W/BroadcastQueue: Background execution not allowed: receiving Intent { act=package.name.action.LOCAL_NOTIFICATION cat=[com.category.LocalNotification] flg=0x14 (has extras) } to package.name/com.category.localnotifications.LocalNotificationReceiver

从我所看到的广播接收器在Android O中受到更多限制,但如果是这样,即使主要活动没有运行,我应该如何安排广播?
我应该使用服务而不是接收器吗?
这是AlarmManager启动代码:
public void Schedule(String aID, String aTitle, String aBody, int aNotificationCode, long aEpochTime) { Bundle lExtras = new Bundle(); lExtras.putInt("icon", f.getDefaultIcon()); lExtras.putString("title", aTitle); lExtras.putString("message", aBody); lExtras.putString("id", aID); lExtras.putInt("requestcode", aNotificationCode); Intent lIntent = new Intent(LocalNotificationScheduler.ACTION_NAME) .addCategory(NotificationsUtils.LocalNotifCategory) .putExtras(lExtras); PendingIntent lPendIntent = PendingIntent.getBroadcast(f.getApplicationContext(), aNotificationCode, lIntent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager lAlarmMgr = (AlarmManager) f.getSystemService(Context.ALARM_SERVICE); lAlarmMgr.set(AlarmManager.RTC, 1000, lPendIntent); }

这是接收者代码:
public class LocalNotificationReceiver extends BroadcastReceiver {public static native voidnativeReceiveLocalNotification (String aID, String aTitle, String aMessage, boolean aOnForeground ); /** This method receives the alarms set by LocalNotificationScheduler, *notifies the CAndroidNotifications c++ class, and (if needed) ships a notification banner */ @Override public void onReceive(Context aContext, Intent aIntent) { Toast.makeText(context, text, duration).show(); }

【AlarmManager和BroadcastReceiver的LocalNotification未在Android O(oreo)中启动】}
Android清单:
< receiver android:name="com.category.localnotifications.LocalNotificationReceiver"> < intent-filter> < action android:name="${applicationId}.action.LOCAL_NOTIFICATION" /> < category android:name="com.category.LocalNotification" /> < /intent-filter> < /receiver>

答案Android O是迄今为止最新的。因此,我尝试消化并提供尽可能准确的信息。
来自https://developer.android.com/about/versions/oreo/background.html#broadcasts
  • 针对Android 8.0或更高版本的应用无法再在其清单中注册隐式广播的广播接收器。 应用程序可以在运行时使用Context.registerReceiver()为任何广播注册接收器,无论是隐式还是显式。
  • 应用可以继续在其清单中注册显式广播。
此外,在https://developer.android.com/training/scheduling/alarms.html中,示例使用显式广播,并未提及有关Android O的任何特殊内容。
我建议你尝试一下如下的明确广播吗?
public static void startAlarmBroadcastReceiver(Context context, long delay) { Intent _intent = new Intent(context, AlarmBroadcastReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, _intent, 0); AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); // Remove any previous pending intent. alarmManager.cancel(pendingIntent); alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delay, pendingIntent); }

报警广播接收器
public class AlarmBroadcastReceiver extends BroadcastReceiver {@Override public void onReceive(Context context, Intent intent) { }}

AndroidManifest中,只需将类定义为
< receiver android:name="org.yccheok.AlarmBroadcastReceiver" > < /receiver>

另一答案今天我有同样的问题,我的通知无效。我认为警报管理器不在奥利奥工作,但问题在于通知。在奥利奥,我们需要添加Channel id。请查看我的新代码:
int notifyID = 1; String CHANNEL_ID = "your_name"; // The id of the channel. CharSequence name = getString(R.string.channel_name); // The user-visible name of the channel. int importance = NotificationManager.IMPORTANCE_HIGH; NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance); // Create a notification and set the notification channel. Notification notification = new Notification.Builder(HomeActivity.this) .setContentTitle("Your title") .setContentText("Your message") .setSmallIcon(R.drawable.notification) .setChannelId(CHANNEL_ID) .build();

检查此解决方案。它像魅力一样工作。
https://stackoverflow.com/a/43093261/4698320
我正在展示我的方法:
public static void pendingListNotification(Context context, String totalCount) { String CHANNEL_ID = "your_name"; // The id of the channel. CharSequence name = context.getResources().getString(R.string.app_name); // The user-visible name of the channel. int importance = NotificationManager.IMPORTANCE_HIGH; NotificationCompat.Builder mBuilder; Intent notificationIntent = new Intent(context, HomeActivity.class); Bundle bundle = new Bundle(); bundle.putString(AppConstant.PENDING_NOTIFICATION, AppConstant.TRUE); //PENDING_NOTIFICATION TRUE notificationIntent.putExtras(bundle); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (android.os.Build.VERSION.SDK_INT > = 26) { NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance); mNotificationManager.createNotificationChannel(mChannel); mBuilder = new NotificationCompat.Builder(context) //.setContentText("4") .setSmallIcon(R.mipmap.logo) .setPriority(Notification.PRIORITY_HIGH) .setLights(Color.RED, 300, 300) .setChannelId(CHANNEL_ID) .setContentTitle(context.getResources().getString(R.string.yankee)); } else { mBuilder = new NotificationCompat.Builder(context) //.setContentText("4") .setSmallIcon(R.mipmap.logo) .setPriority(Notification.PRIORITY_HIGH) .setLights(Color.RED, 300, 300) .setContentTitle(context.getResources().getString(R.string.yankee)); }mBuilder.setContentIntent(contentIntent); int defaults = 0; defaults = defaults | Notification.DEFAULT_LIGHTS; defaults = defaults | Notification.DEFAULT_VIBRATE; defaults = defaults | Notification.DEFAULT_SOUND; mBuilder.setDefaults(defaults); mBuilder.setContentText(context.getResources().getString(R.string.you_have) + " " + totalCount + " " + context.getResources().getString(R.string.new_pending_delivery)); //You have new pending delivery. mBuilder.setAutoCancel(true); mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build()); }

另一答案通过定义显式意图(显式定义广播接收器的类名)来创建AlarmManager:
private static PendingIntent getReminderReceiverIntent(Context context) { Intent intent = new Intent("your_package_name.ReminderReceiver"); // create an explicit intent by defining a class intent.setClass(context, ReminderReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); return pendingIntent; }

另外,在创建实际通知时,不要忘记为Android Oreo(API 26)创建通知通道:
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (VERSION.SDK_INT > = VERSION_CODES.O) { notificationManager.createNotificationChannel(NotificationFactory.createNotificationChannel(context)); } else { notificationManager.notify(NotificationsHelper.NOTIFICATION_ID_REMINDER, notificationBuilder.build()); }

另一答案
尝试这个代码为Android O 8.1
Intent nIntent = new Intent("android.media.action.DISPLAY_NOTIFICATION"); nIntent.addCategory("android.intent.category.DEFAULT"); nIntent.putExtra("message", "test"); nIntent.setClass(this, AlarmReceiver.class); PendingIntent broadcast = PendingIntent.getBroadcast(getAppContext(), 100, nIntent, PendingIntent.FLAG_UPDATE_CURRENT);


    推荐阅读