关于监听通知栏通知的常用方法的记录

第一种方法:使用辅助功能AccessibilityService 相关的就可以实现.

具体使用方法可以参考之前的一篇文章:

自动抢红包-辅助功能的使用 http://blog.csdn.net/lezhang123/article/details/55100133

 

第2 种方法:使用NotificationListenerService.

具体可以先参考知乎的这个链接:https://www.zhihu.com/question/33540416/answer/113706620

这里贴一下,以便后续查看:

更新解决方案:https://gist.github.com/xinghui/b2ddd8cffe55c4b62f5d8846d5545bf9

背景知识:
所属:android.service.notification.NotificationListenerService
作用:监听通知栏内容变化的服务
extends Service,abstract class(意味着第三方可以实现去接收通知栏的通知数据)。
Added in API level 18(Android 4.3)。
应用场景:智能手表(Google官方的Android Wear手机端App,通知消息同步到手表。如下图)、红包助手(监听通知栏的微信红包消息)等。
Service bind时机:在系统的设置通知授权中勾选并授权时。
回调时机:有新通知或通知被移除或通知排序变化时系统回调。

----坑------

应用进程被杀后再次启动时,服务不生效(没有bindService)(在下图所示的蓝色列表名单中,不在红色的存活名单中)。
影响:通知栏有内容变更,服务无法感知。

还原方法:重启手机
必现手机(方便调试):小米Note Pro,清除后台应用后。
我们要做的:让服务重生。
调试手段:查看存活的通知监听服务。
方法:adb shell dumpsys notification

蓝色:已授权的通知监听Service列表。
红色:当前存活的的通知监听Service列表。

调查思路:
一、第三方应用主动注册
二、触发系统重新bind
思路一:第三方应用主动注册

关键代码路径:
android.service.notification.NotificationListenerService#registerAsSystemService
android.app.INotificationManager.Stub#enforceSystemOrSystemUI
条件:系统的uid或有android.permission.STATUS_BAR_SERVICE权限。
∴ 路不通。
思路二:触发系统重新bind
关键代码路径:
com.android.server.notification.ManagedServices#rebindServices

三种方式触发:
A && B(A:应用安装卸载或更新等的广播;B:上图蓝色列表中的服务有变化)。
系统的登录用户切换 。[pass]
Settings.Secure.ENABLED_NOTIFICATION_LISTENERS的Settings值有变更。
第三方有权利触发的方式(源码分析得知 1B= 3):


Service的disable,会有Intent.ACTION_PACKAGE_CHANGED广播,并且从上图蓝色列表中移除。
利用这一特性,把应用的NotificationListenerService实现类disable再enable,即可触发系统rebind操作。

private void toggleNotificationListenerService() {
        PackageManager pm = getPackageManager();
        pm.setComponentEnabledSetting(new ComponentName(this, com.xinghui.notificationlistenerservicedemo.NotificationListenerServiceImpl.class),
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

        pm.setComponentEnabledSetting(new ComponentName(this, com.xinghui.notificationlistenerservicedemo.NotificationListenerServiceImpl.class),
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);


}

问题解决。

补充:
1、怎样在代码中判断自己的服务是否在上图蓝色列表(通知已授权)中?

private static boolean isNotificationListenerServiceEnabled(Context context) {
        Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(context);
        if (packageNames.contains(context.getPackageName())) {
            return true;
        }
        return false;
}

2、怎样发起通知授权流程。

startActivity(new Intent(NotificationConstants.ACTION_NOTIFICATION_LISTENER_SETTINGS));

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值