天天看點

Android:調用NotificationManager.notify 方法無效,通知欄不顯示的原因以及解決辦法

第一步:建立NotificationManager和Notification

val notificationManagerCompat = NotificationManagerCompat.from(context)

val builder: NotificationCompat.Builder = NotificationCompat.Builder(context, CHANNEL_ID)

    // 清楚通知欄時的相應
    .setDeleteIntent(getDeleteIntent(context))

    // 設定自定義通知欄布局
    .setCustomContentView(remoteViews)

    // 設定通知時間,此事件用于通知欄排序
    .setWhen(System.currentTimeMillis())

    // 設定通知欄被點選時的事件
    .setContentIntent(getContentClickIntent(context))

    // 設定優先級,低優先級可能被隐藏
    .setPriority(NotificationCompat.PRIORITY_HIGH)

    // 設定通知欄能否被清楚,true不能被清除,false可以被清除
    .setOngoing(false)

    // 設定通知欄的小圖示,必需設定,否則crash
    .setSmallIcon(R.drawable.notification_icon)



// 此處必須相容android O裝置,否則系統版本在O以上可能不展示通知欄
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val channel = NotificationChannel(
                        context.packageName, 
                        TAG, 
                        NotificationManager.IMPORTANCE_DEFAULT

                  )

                  notificationManagerCompat.createNotificationChannel(channel)

}

// channelId非常重要,不設定通知欄不展示
builder.setChannelId(context.packageName)

// 建立通知欄
val notify: Notification = builder.build()

// 通知系統展示通知欄
notificationManagerCompat.notify(TAG, NOTIFY_ID, notify)
           
  1. 部分android O裝置調用notify方法無效,即不展示通知欄。解決重點在于必須相容android O裝置,否則系統版本在O以上可能不展示通知欄
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val channel = NotificationChannel(
                        context.packageName,
                        TAG,
                        NotificationManager.IMPORTANCE_DEFAULT
                  )
    notificationManagerCompat.createNotificationChannel(channel)
}
           
  1. 在使用Notification展示下載下傳進度的時候,在現在速度極快的情況下,出現了下載下傳完成但是通知欄下載下傳進度卻處于未完成狀态,即 notificationManagerCompat.notify(TAG, NOTIFY_ID, notify) 無效。

    處理方案:是降低notify方法的調用次數,每10%進度更新一次通知欄即可。

源碼中實作通知欄服務的是

frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java
NotificationManager.notify()方法最終調用了NotificationManagerService中的enqueueNotificationInternal()方法

enqueueNotificationInternal中調用checkDisqualifyingFeatures方法對目前應用通知隊列的長度做了校驗
           

源碼:

static final int MAX_PACKAGE_NOTIFICATIONS = ;
private boolean checkDisqualifyingFeatures(int userId, int callingUid, int id, String tag, NotificationRecord r) {

    // ...省略無數代碼...

    // limit the number of outstanding notificationrecords an app can have
    int count = getNotificationCountLocked(pkg, userId, id, tag);

    if (count >= MAX_PACKAGE_NOTIFICATIONS) {

        mUsageStats.registerOverCountQuota(pkg);

        Slog.e(TAG, "Package has already posted or enqueued " + count
        + " notifications. Not showing more. package=" + pkg);

        return false;

    }

    // ...省略無數代碼...

}
           

轉載自:https://blog.csdn.net/z529905310/article/details/81067272