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

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