创建NotificationManager和Notification

val notificationManagerCompat = NotificationManagerCompat.from(context)val builder: NotificationCompat.Builder = NotificationCompat.Builder(context, CHANNEL_ID)    // 清楚通知栏时的相应    .setDeleteIntent(getDeleteIntent(context))    // 设置自定义通知栏布局,support兼容包25以下,找不到此方法    // 需要使用setContent(remoteViews)    .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)}


 

2. 在使用Notification展示下载进度的时候,在现在速度极快的情况下,出现了下载完成但是通知栏下载进度却处于未完成状态,即 notificationManagerCompat.notify(TAG, NOTIFY_ID, notify) 无效。

此现象的原因是因为系统通知栏对单个应用通知队列通长度进行了限制。

notify方法会将Notification加入系统的通知队列,当前应用发出的Notification数量超过50时,不再继续向系统的通知队列添加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;    }    // ...省略无数代码...}

 

至此



 

更多相关文章

  1. Android(安卓)kotlin高级特性
  2. android的ndk修改app_platform的方法,亲测绝对可行
  3. android设置字符串到剪贴板
  4. 编译 Boost for android的库方法
  5. android 广播机制
  6. Android(安卓)动态设置全屏,退出全屏
  7. Android(安卓)Studio之——问题集合及解决方法(对号入座)
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android之传感器(一)
  2. 一种巧妙获取Android状态栏高度的办法
  3. Cocos2dx杂记:仿Android提示Toast
  4. 14天学会安卓开发(第十天)Android网络与
  5. 在eclipse创建android 工程
  6. Android开发学习
  7. 今天的小收获
  8. Android核心分析(链接)
  9. Android(安卓)异步和超时处理 例子
  10. 解决Android9.0网络请求无效问题