【Debug-Notification】RemoteServiceException: Bad notification for startForeground...

写了一个前台通知,在Android5.0设备上测试没问题,换到8.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 vis=PRIVATE)

查看资料:https://blog.csdn.net/misiyuan/article/details/78384819

原来是Android8.0对通知做了细分,引进了channel,这主要影响两个方面:
A。普通通知Notification;B。前台服务通知

而我遇到的就是后者。

A.普通通知Notification:

对于普通通知,对于Android 8.0的适配可参照:https://blog.csdn.net/qq_34773981/article/details/78173376

主要相对于传统的写法修改两处:

①在“NotificationManager”中设置添加“NotificationChannel”属性:

NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

// 【适配Android8.0】给NotificationManager对象设置NotificationChannel
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationChannel channel = new NotificationChannel("notification_id", "notification_name", NotificationManager.IMPORTANCE_LOW);
    notificationManager.createNotificationChannel(channel);
}

②在“Notification”中使用“setChannelId()”方法设置添加“channel_id”属性:

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
...
...
// 【适配Android8.0】设置Notification的Channel_ID,否则不能正常显示
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    builder.setChannelId("notification_id");
}
...
builder.build();

其中,第①步骤中的“NotificationChannel”的构造函数中参数列表依次为:
【channel_id】唯一id,String类型;
【channel_name】对用户可见的channel名称,String类型;
【importance_level】通知的重要程度。

importance_level主要有七种层次:

IMPORTANCE_NONE:      (0)关闭通知。在任何地方都不会显示,被阻塞
IMPORTANCE_MIN:          (1)开启通知。不弹出,不发提示音,状态栏中无显示
IMPORTANCE_LOW:        (2)开启通知。不弹出,不发提示音,状态栏中显示
IMPORTANCE_DEFAULT(3)开启通知。不弹出,发出提示音,状态栏中显示【默认】
IMPORTANCE_HIGH:       (4)开启通知。会弹出,发出提示音,状态栏中显示

IMPORTANCE_MAX:        (5)开启通知。会弹出,发出提示音,可以使用full screen intents(比如来电)。重要程度最高
IMPORTANCE_UNSPECIFIED(-1000)表示用户未设重要值。该值是为了持久的首选项,且永不应该与实际通知相关联

 该部分参考:
https://blog.csdn.net/Haienzi/article/details/81268022    【标题:Android8.0使用通知创建前台服务】
https://www.jianshu.com/p/f85ef58edf63    【标题:Android Oreo 通知新特性,这坑老夫先踩了】

前世今生:

Android O之前,叫通知“优先级”,通过在Build时,setPriority() 设置,共分为5档(-2 ~ 2);
默认值:Notification.PRIORITY_DEFAULT

Android O之后,叫通知“重要性”,通过NotificationChannel的 setImportance() 设置,也是5档(0 ~ 4);
默认值:NotificationManager.IMPORTANCE_DEFAULT

即使你设置了通知声音、震动这些属性,其“重要性”也必须满足下表对应的档位:

ImportanceBehaviorUsageExamples
NONEDon't show in the shadeNormally, Suppressing notification from package by user requestBlocked apps notification
MINNo sound or visual interruptionNon-essential information that can wait or isn’t specifically relevant to the userNearby places of interest, weather, promotional content
LOWNo soundNotification channels that don't meet the requirements of other importance levelsNew content the user has subscribed to, social network invitations
DEFAULTMakes a soundInformation that should be seen at the user’s earliest convenience, but not interrupt what they're doingTraffic alerts, task reminders
HIGHMakes a sound and appears on screenTime-critical information that the user must know, or act on, immediatelyText messages, alarms, phone calls



 

该部分参考: https://www.jianshu.com/p/99bc32cd8ad6    【标题:NotificationChannel 适配填坑指南】

B.前台服务通知:

与前者需要添加的代码相同。

前台服务可通过【startForeground()】方法在通知栏列出前台服务的通知,在传统的写法中类似于普通通知Notification的写法,但是不需要使用NotificationManager来管理显示通知。但是在Android8.0之后引入NotificationChannel之后,即使找不到NotificationManager的使用位置,也是要把【A.普通通知Notification---->①在“NotificationManager”中设置添加“NotificationChannel”属性】中的代码在执行【startForeground();】语句之前写出来。

Intent intent = new Intent(this, TestActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
...
...  
// 【适配Android8.0】设置Notification的Channel_ID,否则不能正常显示
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    builder.setChannelId("notification_id");
}
...
...


// 额外添加:
// 【适配Android8.0】给NotificationManager对象设置NotificationChannel
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    NotificationChannel channel = new NotificationChannel("notification_id", "notification_name", NotificationManager.IMPORTANCE_LOW);
    notificationManager.createNotificationChannel(channel);
}

// 启动前台服务通知
startForeground(1, builder.build());

参见:https://blog.csdn.net/Haienzi/article/details/81268022

  • 9
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值