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 = 50;
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

你可能感兴趣的:(Android随笔)