第一步:建立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)
- 部分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)
}
-
在使用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