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. 【BZOJ2554】Color 概率神题

    [BZOJ2554]Color Description 有n个球排成一列,每个球都有一个颜色,用A-Z的大写字母来表示,我们每次随机选出两个球ball1,ball2,使得后者染上前者的颜色,求期望操作 ...

  2. 二进制状态压缩dp(旅行商TSP)POJ3311

    http://poj.org/problem?id=3311 Hie with the Pie Time Limit: 2000MS   Memory Limit: 65536K Total Subm ...

  3. 模拟退火算法(西安网选赛hdu5017)

    Ellipsoid Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total ...

  4. nginx配置文件内容详情及基本属性配置

    Nginx的配置文件nginx.conf配置详解如下: user nginx nginx ; Nginx用户及组:用户 组.window下不指定 worker_processes 8; 工作进程:数目 ...

  5. Windows安装使用git

    下载安装Windows安装文档Git-2.16.2-64-bit双击安装(安装过程不详述) 打开git客户端 新建代码命令 mkdir /c/code 进入该目录(对应windows的c盘下面的目录) ...

  6. PL/SQL编程基础(三):数据类型划分

    数据类型划分 在Oracle之中所提供的数据类型,一共分为四类: 标量类型(SCALAR,或称基本数据类型) 用于保存单个值,例如:字符串.数字.日期.布尔: 标量类型只是作为单一类型的数据存在,有的 ...

  7. 最近遇到的bug

    1. 地图周边快查,按钮点击没反应 子控件超出了父控件 2.图片显示灰色背景,一直去不掉    设置图片背景图片clear cloro  3. 显示隐藏导航栏  下面两个方法效果不同     self ...

  8. display属性的表格布局相关属性

    基于CSS属性display:table的表格布局的使用   项目改造中遇到DIV+CSS实现的table,新需求需要在表格使用单元格合并,网上调查返现CSS display:table实现的tabl ...

  9. centos Linux系统日常管理1 cpuinfo cpu核数 命令 w, vmstat, uptime ,top ,kill ,ps ,free,netstat ,sar, ulimit ,lsof ,pidof 第十四节课

    centos Linux系统日常管理1  cpuinfo cpu核数   命令 w, vmstat, uptime ,top ,kill ,ps ,free,netstat ,sar, ulimit ...

  10. Flask系列之源码分析(一)

    目录: 涉及知识点 Flask框架原理 简单示例 路由系统原理源码分析 请求流程简单源码分析 响应流程简单源码分析 session简单源码分析 涉及知识点 1.装饰器 闭包思想 def wapper( ...