1. 程式人生 > >安卓8.0通知許可權適配

安卓8.0通知許可權適配

隨著安卓8.0的出現,越來越多的人開始要進行8.0系統的適配了,很多人都知道安卓最近幾個版本的新特性這裡大概說一下:

  1. 5.0的時候出現了Design風格
  2. 6.0出現的危險許可權需要申請
  3. 7.0出現的目錄訪問被限制
  4. 今天要介紹的8.0通知欄的機制
在前一段時間用一個8.0的模擬器測試的時候,傳送notifation(通知)的時候遇到了一個錯誤,如下圖:
列印下來的錯誤資訊: No Channel found for pkg=com.lixuc.demo, channelId=null, id=1, tag=null, opPkg=com.lixuc.demo, callingUid=10081, userId=0, incomingUserId=0, notificationUid=10081, notification=Notification(channel=null pri=0 contentView=null vibrate=default sound=null defaults=0x2 flags=0x10 color=0xff98903b vis=PRIVATE)

跟進NotificationManager的notify方法,呼叫了NotificationManagerService的enqueueNotificationWithTag將通知入隊,最後在NotificationManagerService的enqueueNotificationInternal方法中發現了error log的蹤跡,擷取程式碼片如下圖:這裡寫圖片描述

見圖可知,是由於此條通知沒有查詢到應用中對應的NotificationChannel的原因,而無法彈出來。那NotificationChannel是個什麼鬼,查閱官文得知,這是Android O新增的通知渠道,其允許您為要顯示的每種通知型別建立使用者可自定義的渠道。使用者介面將通知渠道稱之為通知類別。

先貼出我猜到坑的錯誤程式碼:


這裡的NotificationCompat及NotificationManagerCompat來自官方提供的相容庫: 
com.android.support:appcompat-v7:26.1.0 
想著最新的Compat庫相容應該做得是最好的,然後錯就錯在這句程式碼: 
NotificationCompat.Builder(context, Integer.toString(notificationId)); 
一眼看到Builder建構函式的第二個引數,傳的是id,就直接把notificationId傳進去了,其實細看傳的是channelId,我這裡把channelId和notificationId概念搞混了。channelId傳null,或者只有一個引數的Builder的構造方法,都不會出現錯誤,修正程式碼如下:

NotificationCompat.Builder builder = new NotificationCompat.Builder(context, null);

//或者
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
  • 1
  • 2
  • 3
  • 4

原理就是:NotificationChannel是Android O新增的特性,為了相容老程式碼,如果channelId為null的話,Android O會把通知歸到“Other Channel”上。 
PS:將targetSdkVersion提到26以上的話,就必須設定channel了,不能為null。

下面來說一下我的解決方法

首先建立channel資訊:

如果你需要傳送屬於某個自定義渠道的通知,你需要在傳送通知前建立自定義通知渠道,示例如下:

 NotificationChannel channel = new NotificationChannel("1",
                "Channel1", NotificationManager.IMPORTANCE_DEFAULT);
        channel.enableLights(true); //是否在桌面icon右上角展示小紅點
        channel.setLightColor(Color.RED); //小紅點顏色
        channel.setShowBadge(true); //是否在久按桌面圖示時顯示此渠道的通知
然後建立通知後,向自定義渠道傳送通知
 int notificationId = 0x1234;
        Notification.Builder builder = new Notification.Builder(context,"1"); //與之前建立的channelId對應
        //icon title text必須包含,不然影響桌面圖示小紅點的展示
        builder.setSmallIcon(android.R.drawable.stat_notify_chat)
                .setContentTitle("xxx")
                .setContentText("xxx")
                .setNumber(3); //久按桌面圖示時允許的此條通知的數量

        notificationManager.notify(notificationId, builder.build());
刪除掉某個渠道:
NotificationChannel mChannel = mNotificationManager.getNotificationChannel(id);
mNotificationManager.deleteNotificationChannel(mChannel);

如果你的應用裡面有通知的話,恰巧你的targetSdkVersion是26以上的情況下,你就需要進行以上的操作了

大家都有了以上相同的教程,但是人和人之間的區別在於:別人有顆更強大的內心,可怕的是比你聰明的人比你還要更努力!!

當你下定決心,準備前行的時候,剩下的只有堅持了。。。

如果大家覺得我寫的還可以的話,請關注我的微信公眾號: