RemoteServiceException: Bad notification for startForeground...

原文链接: https://blog.csdn.net/dandelionela/article/details/86092293

写了一个前台通知,在Android5.0设备上测试没问题,换到8.0之后报错:

  1. android.app.RemoteServiceException: Bad notification for startForeground:
  2. java.lang.RuntimeException: invalid channel for service notification:
  3. 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”属性:

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

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

  1. NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
  2. ...
  3. ...
  4. // 【适配Android8.0】设置Notification的Channel_ID,否则不能正常显示
  5. if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  6. builder.setChannelId("notification_id");
  7. }
  8. ...
  9. 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

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

Importance Behavior Usage Examples
NONE Don't show in the shade Normally, Suppressing notification from package by user request Blocked apps notification
MIN No sound or visual interruption Non-essential information that can wait or isn’t specifically relevant to the user Nearby places of interest, weather, promotional content
LOW No sound Notification channels that don't meet the requirements of other importance levels New content the user has subscribed to, social network invitations
DEFAULT Makes a sound Information that should be seen at the user’s earliest convenience, but not interrupt what they're doing Traffic alerts, task reminders
HIGH Makes a sound and appears on screen Time-critical information that the user must know, or act on, immediately Text messages, alarms, phone calls



 

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

B.前台服务通知:

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

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

  1. Intent intent = new Intent(this, TestActivity.class);
  2. PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
  3. NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
  4. builder.setSmallIcon(R.drawable.ic_launcher);
  5. builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
  6. ...
  7. ...
  8. // 【适配Android8.0】设置Notification的Channel_ID,否则不能正常显示
  9. if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  10. builder.setChannelId("notification_id");
  11. }
  12. ...
  13. ...
  14. // 额外添加:
  15. // 【适配Android8.0】给NotificationManager对象设置NotificationChannel
  16. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  17. NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
  18. NotificationChannel channel = new NotificationChannel("notification_id", "notification_name", NotificationManager.IMPORTANCE_LOW);
  19. notificationManager.createNotificationChannel(channel);
  20. }
  21. // 启动前台服务通知
  22. startForeground(1, builder.build());

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章