http://www.eoeandroid.com/thread-148381-1-1.html

最近在网上搜索怎样绕开QQ通讯录和360的广播中断,在它们之前拿到短信,结果很遗憾没有搜索到什么东西,反而搜索到一些炫耀的帖子,只说自己解决了,不给别个分享解决方案的。

我只好自己来弄一下这个东东。

本来以为腾讯是拦截ril层的消息,然后阻断广播的发送,但是这种方式要修改framework才可能实现。

反编译QQ通讯录代码,没有看到特殊的设置,反编译360,发现了其中的奥秘。

这要从广播特别是有序广播的分发机制说起,底层的代码还有待我们的研究。

我没怎么看底层代码,只有测试实践。

经过我多次测试发现:

广播分2种,无序广播和有序广播。可以理解为散列和队列广播。



首先无序广播,不能中断,分发机制有点类似散列发送。这种广播的的发送为:context.sendBroadcast

这种广播是不能中断的,请看API说明。

其次为有序广播,可以中断。

这种广播,以我的理解可能存在很大的BUG,短信这块广播的发送BUG现在被QQ和360利用,可能在以后的版本中会修订。

它是一个按一种优先级顺序发送,即按某种messagequere队列发送,其中队列中的任何广播接收者都可以终端该广播,导致它之后的成员不能接收到广播。

我们首先看这个队列是怎么形成的:(以下是假想+测试验证,有待代码验证)

假设我们广播优先级别都设成:2147483647(注:最大int形整数)



首先动态注册优先级别最高

其次静态注册



在动态注册中

最早动态注册优先级别最高



在静态注册中

最早安装的程序,静态注册优先级别最高(注:安装APK会解析af.xml,把其加入队列)

注意这里安装 是指adb install xxx.apk或者手机上安装应用。

然后才是adb push到其他目录的应用

可能的原因是手机查询应用的时候会先去特定目录解析应用,所以广播注册会出现这种差别。adb push 到system/app下会比安装的优先级高吗?这有待你的验证,我还没验证。



然后都是安装的应用中

首先安装的优先等级最高



OK 以上就是我分析的有序广播的优先级别问题。



反编译360源码会发现,他首先静态注册的广播接收器里面设置的优先数量级为2147483647,然后在广播中启动一个service,在service中注册了一个优先数量级为2147483647的同样的广播接收器。

就这么简单就实现了没有同种实现的应用的情况下拦截短信。



OK,我们现在以同样的方式来做一个实验:

首先写一个应用,注册一个开机完成广播接收者。

<receiver android:name=".MyBrocast" android:permission="android.permission.BROADCAST_SMS">

            <intent-filter android:priority="2147483647">

                <action android:name="android.provider.Telephony.SMS_RECEIVED" />

            </intent-filter>

            <intent-filter android:priority="2147483647">

                <action android:name="android.intent.action.BOOT_COMPLETED" />

            </intent-filter>

        </receiver>



然后在这个广播接收者接收到信息之后马上启动一个service

public void onReceive(Context context, Intent intent) {

                Log.v("MyBrocast.onReceive", "testtttttttttttt");

                if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){

                        Intent service=new Intent(context, MyService.class);

                        context.startService(service);

                }

然后在service重新注册一个接收短信的广播接收者,优先级2147483647

IntentFilter localIntentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");

            localIntentFilter.setPriority(2147483647);

            myService = new MyBrocast();

            MyBrocast localMessageReceiver = myService;

            Log.v("MyBrocast.onReceive", "onCreate");

            Intent localIntent = registerReceiver(localMessageReceiver, localIntentFilter);



这种重启手机就OK了,你也可以让360,QQ郁闷的。







当然这里分享这个信息主要是想和大家一起提高,360和QQ的android版还是做的相当好的,有许多我们借鉴的地方。

其实我们也可以认为这是telephone模块的一个BUG,据说以前的版本是无序广播,不知是否出于拦截短信的机制修改了,反正我觉得有被第3方应用滥用的可能。



测试源码很简单,这里就不贴了

这里测试代码有很多不完善,比如服务被杀或者没有启动什么的。我们可以考虑把服务进程挂载到重要进程上去。



<-----------------------------------------------更新分割线----------------------------------------------------->

前面理解可能有点偏差,下面是我研究了一下代码部分验证了我的推论,能力有限还没能完全验证。

这个方法说明,如果我们的优先级设置为最大int形整数是能够排在最前面的。



到这里我们发现,优先级设置最高的会排在前面,如果优先级相同则按默认的排序不动,那么现在默认的排序是怎么样的呢?



我们发现大部分广播发送者都是只传送一个action,所以我们关注:

if (resolvedType == null && scheme == null && intent.getAction() != null) {

            firstTypeCut = mActionToFilter.get(intent.getAction());

            if (debug) Slog.v(TAG, "Action list: " + firstTypeCut);

        }

mActionToFilter内部list的排序决定了同样优先级情况下的排序问题

首先我们跟踪比较容易跟踪的

1.动态注册

AMS中的registerReceiver方法中有对变量mReceiverResolver的操作

如下:

BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);

            rl.add(bf);

            if (!bf.debugCheck()) {

                Slog.w(TAG, "==> For Dynamic broadast");

            }

            mReceiverResolver.addFilter(bf);



这里验证了同样优先级的情况下先动态注册的排在后来动态注册的广播接收者的前面。------------------1OK



2.静态注册

我们首先跟踪到PackageManagerService中的queryIntentReceivers方法

ComponentName comp = intent.getComponent();一般为空,略过。

因为广播一般不会发送给某个指定的包,所以最终一般会调用

if (pkgName == null) {

                return (List<ResolveInfo>)mReceivers.queryIntent(intent,

                        resolvedType, flags);

            }



这里会调用到IntentResolver的public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly) 方法

这里同样是找mActionToFilter中的值,说明这个对象里面可以动态赋值给它(动态注册AMS中的registerReceiver方法中有对变量mReceiverResolver)

也可以静态赋值,那么我们现在关注的就是mf.xml中的赋值顺序。但是到这里跟踪不下去了,感觉是安装的时候packageManageservice做了某种特殊的设置,adb install和adb push也做了不同的操作,

我还没有研究PMS,希望高手能解释下



-------------2 not ok



继续回来看AMS的broadcastIntentLocked方法

if (!ordered && NR > 0) {

如果不是队列广播这里会先立即给动态注册的广播接收者发送消息 ------------------------------------3OK一部分

并且这里还说明了一个问题:就是非ordered的广播基本都是动态注册优先接收到信息,无论动态注册的优先级多低(有的情况也不是这样的,具体见源代码)

继续

if (receivers != null) {

这里只要有静态注册的一般不为空

int NT = receivers != null ? receivers.size() : 0;

            int it = 0;

            ResolveInfo curt = null;

            BroadcastFilter curr = null;

            while (it < NT && ir < NR) {

                if (curt == null) {

                    curt = (ResolveInfo)receivers.get(it);

                }

                if (curr == null) {

                    curr = registeredReceivers.get(ir);

                }

                if (curr.getPriority() >= curt.priority) {

                    // Insert this broadcast record into the final list.

                    receivers.add(it, curr);

                    ir++;

                    curr = null;

                    it++;

                    NT++;

                } else {

                    // Skip to the next ResolveInfo in the final list.

                    it++;

                    curt = null;

                }

            }

这一段仅仅是把动态注册的优先级一样的广播加在了静态注册的前面,这里完全验证了动态注册优先静态注册----------------------3OK



代码后面的就是发送广播了。



现在的代码验证情况就是静态注册先安装的先获得广播还没能验证。希望高手能现场解释下。邮箱minzhang4891@sina.com

怎样绕开QQ通讯录和360的广播中断的更多相关文章

  1. QQ通讯录VS360通讯录对新建信息界面中草稿的处理

    在新建信息界面中,对草稿信息的处理. 1. QQ通讯录的处理是: 如果信息编辑框不为空,点击HOME键或者点击BACK键,保存草稿,同时结束新建信息界面. 如果收件人为空,也保存草稿,只是将收件人取名 ...

  2. qq通讯录

  3. Android项目--获取系统通讯录列表

    ----------------- 通讯录列表 ----------------- 按常理来说,获取系统通讯录列表,无非就是将通讯录的数据库打开获取数据,适配,添加即可. Cursor cursor; ...

  4. iOS开发系列--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开发汇总

    --系统应用与系统服务 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用 ...

  5. iOS开发系列通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开

    --系统应用与系统服务 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用 ...

  6. iOS开发系列--通讯录、蓝牙、

    iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务: ...

  7. 转--2014年最新810多套android源码2.46GB免费一次性打包下载

    转载自:http://www.eoeandroid.com/thread-497046-1-1.html 感谢该博客主人无私奉献~~ 下面的源码是从今年3月份开始不断整理源码区和其他网站上的安卓例子源 ...

  8. 2014年最新720多套Android源码2.0GB免费一次性打包下载

    之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年3月份开始不断整理源码区和其他网站上的android源码,目前总共有720套左右,根据实现的功能被我分成了100多个类,总共 ...

  9. ym——android源代码大放送(实战开发必备)

    转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! 目录 PATH 列表 卷序列号为 000A-8F50 E:. │  javaapk.c ...

随机推荐

  1. 【BZOJ2314】士兵的放置 树形DP

    [BZOJ2314]士兵的放置 Description 八中有N个房间和N-1双向通道,任意两个房间均可到达.现在出了一件极BT的事,就是八中开始闹鬼了.老大决定加强安保,现在如果在某个房间中放一个士 ...

  2. 【BZOJ4196】[Noi2015]软件包管理器 树链剖分

    [Noi2015]软件包管理器 树链剖分 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从 ...

  3. python 10分钟入门pandas

    本文是对pandas官方网站上<10 Minutes to pandas>的一个简单的翻译,原文在这里.这篇文章是对pandas的一个简单的介绍,详细的介绍请参考:Cookbook .习惯 ...

  4. 170620、springboot编程之页面版Hello World

    书接上回,把Hello World 在页面上显示! 1.在pom文件中加入web支持 <dependency> <groupId>org.springframework.boo ...

  5. FNV hash算法

    原文:https://blog.csdn.net/u013137970/article/details/79020095 FNV算法简介FNV算法属于非密码学哈希函数,它最初由Glenn Fowler ...

  6. Spring boot官方文档学习(一)

    个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念, ...

  7. FW:stash install

    先下载破解安装包.http://pan.baidu.com/s/1mgumBbE 我的安装环境. 说明下,经过我的测试. 如果系统内存低于 512M, 就不要折腾了,非常卡. 推荐 2048M 内存. ...

  8. 大话存储1——存储系统的发展,计算机I/O

    1 存储发展 存储在这里的含义为信息记录,是伴随人类活动出现的技术. 1. 竹简和纸张 竹简是中国古代使用的记录文字的工具,后来被纸张所取代,如图1.1所示. 2. 选数管 选数管是20世纪中期出现的 ...

  9. CSS伪代码

    /*在p之后插入我是好人*/ p.first:after { content: "好人" } /*在p之前插入亲爱的朋友men*/ p:before { content: &quo ...

  10. 优雅的使用Laravel之phpstorm配置

    优雅的使用Laravel之phpstorm配置 先打开一个Laravel 项目,然后在project tool 窗口选择根节点.然后右键->Composer | Init composer . ...