状态栏显示应用通知但activeNotifications.size为0,如何获取活跃通知信息?
问题原因及解决办法
1. 权限缺失(Android 13+)
从Android 13(API 33)开始,应用需申请POST_NOTIFICATIONS权限才能发布通知,同时获取自身活跃通知也依赖该权限。若你的应用目标SDK为33+,请按以下步骤操作:
- 在
AndroidManifest.xml中声明权限:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
- 运行时动态申请权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1001) } }
2. 前台服务通知的特殊检查逻辑
若你的通知是通过前台服务startForeground()发布的,部分Android版本中NotificationManager.activeNotifications()可能无法正确返回该通知。此时可通过检查前台服务运行状态间接判断通知是否存在:
fun isMyServiceRunning(serviceClass: Class<*>): Boolean { val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager for (service in manager.getRunningServices(Integer.MAX_VALUE)) { if (serviceClass.name == service.service.className) { return true } } return false } // 使用示例 if (isMyServiceRunning(MyService::class.java)) { // 前台服务运行中,对应通知处于显示状态 }
注:Android 14(API 34)开始,
getRunningServices()仅返回自身应用的前台服务,完全适配需求。
3. 确认通知归属进程
若MyService在独立进程中运行(AndroidManifest给service设置了android:process属性),MainActivity所在进程的NotificationManager无法获取该进程发布的通知。解决方式:
- 移除
android:process属性,让服务与Activity同进程; - 或在服务进程中实现通知检查逻辑,通过跨进程通信(如Messenger、AIDL)将结果同步给MainActivity。
4. 备选方案:使用NotificationListenerService
若以上方法无效,可通过NotificationListenerService监听通知的显示/消失状态:
- 在AndroidManifest中声明服务:
<service android:name=".MyNotificationListener" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> <intent-filter> <action android:name="android.service.notification.NotificationListenerService" /> </intent-filter> </service>
- 实现服务类:
class MyNotificationListener : NotificationListenerService() { override fun onNotificationPosted(sbn: StatusBarNotification?) { super.onNotificationPosted(sbn) sbn?.let { if (it.id == MyService.NOTIFICATION_ID && it.packageName == packageName) { // 通知已显示,可通过广播/EventBus通知MainActivity } } } override fun onNotificationRemoved(sbn: StatusBarNotification?) { super.onNotificationRemoved(sbn) sbn?.let { if (it.id == MyService.NOTIFICATION_ID && it.packageName == packageName) { // 通知已消失,可通过广播/EventBus通知MainActivity } } } }
- 引导用户开启通知监听权限:
fun openNotificationListenerSettings() { val intent = Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS") startActivity(intent) }
注:该方案需用户手动授权,适合对通知状态实时性要求高的场景。
内容的提问来源于stack exchange,提问作者Hyejung
相关产品推荐
相关产品推荐

