Android应用关闭或被杀死时如何读取通知且不在状态栏显示?
Android NotificationListenerService 杀后台后仍可监听通知的实现方案
1. 失效核心原因
NotificationListenerService 本身由系统进程托管,但Android高版本的后台进程限制、国内定制ROM的省电策略,会在应用被主动杀死时直接回收该服务,导致通知监听中断。
2. 基础服务配置优化
首先在AndroidManifest.xml中正确注册监听服务,确保系统能识别并绑定你的服务:
<service android:name=".CustomNotificationListener" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> <intent-filter> <action android:name="android.service.notification.NotificationListenerService" /> </intent-filter> </service>
其次在自定义的监听服务中重写断开回调,触发时主动请求重绑服务:
@Override public void onListenerDisconnected() { // Android 7.0及以上支持主动请求重绑 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { requestRebind(new ComponentName(this, CustomNotificationListener.class)); } }
3. 进程保活配置
- 引导用户开启应用自启动权限:不同ROM的权限路径不同,可直接跳转对应系统设置页让用户手动开启,允许应用被系统后台自动重启。
- 加入电池优化白名单:引导用户关闭系统对当前应用的电池优化限制,避免省电策略触发时杀死应用进程。
- 搭配前台服务保活:启动一个常驻前台服务,提升应用进程优先级,降低被系统查杀的概率,Android 8.0及以上需要为前台服务单独创建通知渠道展示常驻通知。
- 每次应用启动时校验通知访问权限:如果权限被系统回收,立刻引导用户重新开启,避免权限失效。
4. 目标应用通知拦截逻辑
在onNotificationPosted回调中匹配目标应用包名,匹配成功后直接取消通知即可实现拦截:
@Override public void onNotificationPosted(StatusBarNotification sbn) { String packageName = sbn.getPackageName(); // 匹配WhatsApp、Facebook、Instagram包名 if (packageName.equals("com.whatsapp") || packageName.equals("com.facebook.katana") || packageName.equals("com.instagram.android")) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cancelNotification(sbn.getKey()); } else { cancelNotification(sbn.getPackageName(), sbn.getTag(), sbn.getId()); } } }
特殊说明
部分国内定制ROM(小米、华为、vivo、OPPO等)有独立的后台进程管理策略,即使完成上述配置,用户主动杀死应用后仍可能无法重启服务,需要针对对应ROM做单独的权限引导适配。
内容的提问来源于stack exchange,提问作者Mayank Balar
相关产品推荐
相关产品推荐

