【问题标题】:Notifications not working on Api 27(8.1.0)通知不适用于 Api 27(8.1.0)
【发布时间】:2023-03-24 04:06:01
【问题描述】:

通知适用于 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 创建通知通道,但它仍然不适用于 Oreo 8.1.0。我还提到了其他堆栈溢出link,但不知道为什么会在我的情况下发生此错误。

UpdateAlarmActivity.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 类,我在其中实现通知的代码。请帮助我或给我一些建议如何解决此错误。

【问题讨论】:

    标签: android push-notification


    【解决方案1】:

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

    频道是分类所有类型的通知了解更多关于通知频道

    check this 用于通知渠道

    **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);
    }**
    

    【讨论】:

    • 感谢您的回答,但我已经浏览了您提供的链接,并且还创建了通知渠道。它显示在我上面的代码中,但它不起作用。
    • change build .gradle compileSdkVersion 27 to 26 and Build Tools version (26.0.2) will help to send notification on app OnDestroy and onPause
    • 它可以工作,但有时它会导致运行时异常我这不是一个好方法,因为 libray 版本应该总是最新的
    • 哪种运行时异常,请解释一下
    • 喜欢 dex 冲突并在 build.gradle 中显示已弃用的 api
    【解决方案2】:

    更改 NotificationCompat.Builder 构造函数:

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
    

    添加频道 ID:

    NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
    

    【讨论】:

    • 感谢您的回答,我试过了,但现在仍然有效。通知适用于 Oreo 8.0,但不适用于 Oreo 8.1.0。
    • 我正在使用vivo v9 oreo 8.1.0..我无法获得fcm设备ID。您有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多