创建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 Studio之——问题集合及解决方法(对号入座)
  2. 编译 Boost for android的库方法
  3. Android 中设置全屏的方法
  4. JS怎样调用Android本地原生方法
  5. asynchttpclient post方法使用
  6. Android Studio支持Java8方法
  7. Android 分多次(每次一个)请求权限时的onRequestPermissionsResult
  8. Android EditText得到焦点失去焦点处理方法

随机推荐

  1. Android API Guides---App Manifest
  2. Android之Button按钮点击事件的四种方式
  3. Android 完美解决自定义preference与Acti
  4. Android中关于签名的一些知识
  5. mac zsh 配置 adb 环境变量 “zsh: comma
  6. Android(安卓)jni开发 eclipse 删除额外
  7. android新闻项目、饮食助手、下拉刷新、
  8. android 实现按两次back键提示退出应用界
  9. 解决 android 4.2 连接 leap wifi 网络
  10. [Android] Handler的具体用法