android - 通知不适用于 Api 27(8.1.0)

标签 android push-notification

通知适用于 Oreo 8.0(Api 26) 及以下版本,但它们不适用于 Oreo 8.1.0。

下面是错误的堆栈跟踪

 android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=null pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 actions=2 vis=PRIVATE)
                                                                             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1768)
                                                                             at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                             at android.os.Looper.loop(Looper.java:164)
                                                                             at android.app.ActivityThread.main(ActivityThread.java:6494)
                                                                             at java.lang.reflect.Method.invoke(Native Method)
                                                                             at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

我正在为 Oreo 创建通知 channel ,但它不适用于 Oreo 8.1.0。我还引用了其他堆栈溢出 link但不知道为什么在我的案例中会出现此错误。

更新警报 Activity .java

public class UpcomingAlarmReceiver extends BroadcastReceiver {

    public static final String TAG = "UpcomingAlarmReceiver";
    public static final String ACTION_DISMISS_NOW = "com.funswitch.funrooster.action.DISMISS_NOW";
    public static final String ACTION_CANCEL_NOTIFICATION = "com.funswitch.funrooster.action.CANCEL_NOTIFICATION";
    public static final String ACTION_SHOW_SNOOZING = "com.funswitch.funrooster.action.SHOW_SNOOZING";
    public static final String EXTRA_ALARM = "com.funswitch.funrooster.extra.ALARM";
    public static final String CHANNEL_NAME = "CHANNEL_NOTIFICATION";
    String NOTIFICATION_CHANNEL_ID = "io.funswitch.funrooster.Channel";


    @Override
    public void onReceive(final Context context, final Intent intent) {
        final byte[] alarmBytes = intent.getByteArrayExtra(EXTRA_ALARM);
        // Un-marshall the bytes into a parcel and create our Alarm with it.
        final Alarm alarm = ParcelableUtil.unmarshall(alarmBytes, Alarm.CREATOR);
        if (alarm == null) {
            throw new IllegalStateException("No alarm received");
        }
        final long id = alarm.getId();
        final NotificationManager nm = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        final boolean actionShowSnoozing = ACTION_SHOW_SNOOZING.equals(intent.getAction());
        if (intent.getAction() == null || actionShowSnoozing) {
            // Prepare notification
            // http://stackoverflow.com/a/15803726/5055032
            // Notifications aren't updated on the UI thread, so we could have
            // done this in the background. However, no lengthy operations are
            // done here, so doing so is a premature optimization.
            String title;
            String text;
            if (actionShowSnoozing) {
                if (!alarm.isSnoozed()) {
                    throw new IllegalStateException("Can't show snoozing notif. if alarm not snoozed!");
                }
                title = alarm.getLabel().isEmpty() ? context.getString(R.string.alarm) : alarm.getLabel();
                text = context.getString(R.string.title_snoozing_until,
                        formatTime(context, alarm.snoozingUntil()));
            } else {
                // No intent action required for default behavior
                title = context.getString(R.string.upcoming_alarm);
                text = formatTime(context, alarm.ringsAt());
            }
            Intent dismissIntent = new Intent(context, UpcomingAlarmReceiver.class)
                    .setAction(ACTION_DISMISS_NOW)
                    .putExtra(EXTRA_ALARM, ParcelableUtil.marshall(alarm));
            NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
            PendingIntent piDismiss = PendingIntent.getBroadcast(context, (int) id,
                    dismissIntent, PendingIntent.FLAG_CANCEL_CURRENT);
            mBuilder
                    .setSmallIcon(R.drawable.ic_alarm_24dp)
                    .setContentTitle(title)
                    .setContentText(text)
                    .addAction(R.drawable.ic_dismiss_alarm_24dp,
                            context.getString(R.string.dismiss_now), piDismiss);

            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                int importance = NotificationManager.IMPORTANCE_HIGH;
                NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, CHANNEL_NAME, importance);
                notificationChannel.enableLights(true);
                notificationChannel.setLightColor(Color.RED);
                notificationChannel.enableVibration(true);
                notificationChannel.setSound(null, null);
                notificationChannel.setShowBadge(false);
                notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
                assert nm != null;
                mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
                nm.createNotificationChannel(notificationChannel);
            }
            Objects.requireNonNull(nm).notify(TAG, (int) id, mBuilder.build());
        } else if (ACTION_CANCEL_NOTIFICATION.equals(intent.getAction())) {
            Objects.requireNonNull(nm).cancel(TAG, (int) id);
        } else if (ACTION_DISMISS_NOW.equals(intent.getAction())) {
            new AlarmController(context, null).cancelAlarm(alarm, false, true);
        }


    }
}

上面是我的 Java 类,我在其中实现了通知代码。请帮助我或给我一些如何解决此错误的建议。

最佳答案

在 api 级别 27 中,谷歌更改了通知方法,现在在 api 27 或更高级别中,您需要创建通知 channel 来发送通知。

Channel 是分类所有类型的通知了解更多关于通知 channel

check this对于通知 channel

**if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
   NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
   String id = "id_product";
   // The user-visible name of the channel.
   CharSequence name = "Product";
   // The user-visible description of the channel.
   String description = "Notifications regarding our products";
   int importance = NotificationManager.IMPORTANCE_MAX;
   NotificationChannel mChannel = new NotificationChannel(id, name, importance);
   // Configure the notification channel.
   mChannel.setDescription(description);
   mChannel.enableLights(true);
   // Sets the notification light color for notifications posted to this
   // channel, if the device supports this feature.
   mChannel.setLightColor(Color.RED);
   notificationManager.createNotificationChannel(mChannel);
}**

关于android - 通知不适用于 Api 27(8.1.0),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50529138/

相关文章:

java - 如何将图像链接到另一个 xml 布局?

android - 在 Activity/普通类中获取 Android 共享首选项值

java - 如何根据对象从 map 中检索值

javascript - 我如何将数据(如用户 ID)传递给网络 worker 以从服务器获取额外的推送通知数据?

java - postgresql - java - 当数据库中发生某些事情时唤醒应用程序

ios - 找不到 OneSignal Swift 安装文件

java - serverSocket.accept() 缓慢或无响应

android - Firebase 通知未以高优先级发送

node.js - 如何将通知从 node.js 服务器发送到 android 客户端。

Cordova PushPlugin 注册出现错误