使用Xposed拦截应用通知的一直简单实现

来源:互联网 发布:java时间格式化DD 编辑:程序博客网 时间:2024/05/01 07:54

当我们不希望某一应用的通知在通知栏上提示时,我们可以通过xposed来实现拦截它的操作。以支付宝为例,当支付宝切换到后台时,信息会以通知栏的形式显示。若要拦截它,大致有两个思路来实现:1、反编译支付宝代码,将相关代码hook掉。然而这个工程对我等小码仔来说,太难实现。2、拦截系统所有的通知信息,对其进行过滤,当信息是来自我们想要拦截的应用时,hook掉它。本文记录一下对第二种方法的简单实现。
基于面向google(baidu)编程,这里决定hook NotificationManager中notify方法,源码如下:

/**   * Post a notification to be shown in the status bar. If a notification with   * the same tag and id has already been posted by your application and has not yet been    * canceled, it will be replaced by the updated information.   *   * @param tag A string identifier for this notification.  May be {@code null}.   * @param id An identifier for this notification.  The pair (tag, id) must be unique   *        within your application.   * @param notification A {@link Notification} object describing what to   *        show the user. Must not be null.   */  public void notify(String tag, int id, Notification notification){       notifyAsUser(tag, id, notification, new UserHandle(UserHandle.myUserId()));  }

notify方法的三个入参,其中notification就是要在通知栏上显示的信息。代码如下(测试时使用QQ来测试,所以注释中有QQ的包名):

public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {    if (!lpparam.packageName.equals("com.eg.android.AlipayGphone")            && !lpparam.processName.equals("com.eg.android.AlipayGphone"))        return;    if (lpparam.packageName.equals("com.eg.android.AlipayGphone")) {        //        if (!lpparam.packageName.equals("com.tencent.mobileqq")        //                && !lpparam.processName.equals("com.tencent.mobileqq"))        //            return;        //        if (lpparam.packageName.equals("com.tencent.mobileqq")) {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {            XposedHelpers.findAndHookMethod("android.app.NotificationManager"                    , lpparam.classLoader, "notify"                    , String.class, int.class, Notification.class                    , new XC_MethodHook() {                        @Override                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {                            XposedBridge.log("methodHookParam.args:  " + Arrays.toString(param.args));                            //通过param拿到第三个入参notification对象                            Notification notification = (Notification) param.args[2];                            //获得包名                            String aPackage = notification.contentView.getPackage();                            String title = "--";                            String text = "--";                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                                Bundle bundle = notification.extras;                                title = (String) bundle.get("android.title");                                text = (String) bundle.get("android.text");                            }                            //    if ("com.tencent.mobileqq".equals(aPackage)) {                            if ("com.eg.android.AlipayGphone".equals(aPackage)                                    && title.equals("支付宝消息") &&                                    text.endsWith("已成功向你转了1笔钱")) {                                param.setResult(null);                                return;                            }                            super.beforeHookedMethod(param);                        }                    });        }}

上面代码实现的是拦截支付宝的到账通知(支付宝还会正常到账,打开支付宝后也会有到账消息,只是拦截了通知栏的提示不影响正常功能),通过notification.extra可以获得要显示在通知栏的信息内容。

    Bundle[{android.title=leon, android.subText=null,   android.showChronometer=false,   android.icon=2130837513,     android.text=leon:九分风好  大, android.progress=0,     android.progressMax=0,    android.rebuild.contentViewActionCount=41,   android.showWhen=true,    android.rebuild.applicationInfo=ApplicationInfo {1a3b2b0 com.eg.android.AlipayGphone},    android.largeIcon=android.graphics.Bitmap@1810ab9, android.infoText=null, android.originatingUserId=0,    android.progressIndeterminate=false}]  

可以看到这是一个bundle对象,其中android.title是通知栏显示的标题,android.text是通知栏显示的内容。这条是支付宝接收到用户发送消息时的内容,下面看一下接收到转账提示时的内容。

    Bundle[{android.title=支付宝消息, android.subText=null, android.showChronometer=false, android.icon=2130837513,    android.text=leon已成功向你转了1笔钱, android.progress=0, android.progressMax=0,    android.rebuild.contentViewActionCount=41, android.showWhen=true,    android.rebuild.applicationInfo=ApplicationInfo{1a3b2b0 com.eg.android.AlipayGphone},    android.largeIcon=android.graphics.Bitmap@33eef20a, android.infoText=null,    android.originatingUserId=0,android.progressIndeterminate=false}]  

可以看到当信息来自支付宝转账时,android.title的内容固定为支付宝消息,android.text的内容为XXX已成功想你转了1笔钱,其余内容全部相同。我们就可以考虑判断这两个字段的值,来对到账消息进行拦截的同时不影响正常功能的使用。代码在上面,很简单的实现了对支付宝到账信息的拦截,若有需要对到账信息统计的话,可以在统计到账的次数与转账人,但是无法统计到账金额,毕竟只是对系统方法进行hook,支付宝也不会把金额信息给显示在通知栏中。

0 0