导读:我们以如何抢先开机启动为例,来说明接收无序广播的静态广播接收器的接收顺序

(注意,文本只是陈述结果,所以叫结果篇,之后的文章再给出源码分析)

首先先说一下android中的广播和广播接收器
广播可以分为有序、无序和sticky共三种
广播接收器可以分为静态和动态两种

首先我们要明确两个问题
1.接收无序广播的接收器接收到广播的顺序是有序的
2.接收无序广播的接收器也一样可以设置优先级的

这里主要说一下多个应用中的静态广播接收器(优先级都相同的情况下
)接收无序广播时的接收顺序


注意:这里主要描述结论,具体原理后续给出


注意:本文在提及的同时出现在同一设备的静态接收器默认具有相同的优先级,这点很重要

我们以开机时候发出的广播android.intent.action.BOOT_COMPLETED为例,这是个无序广播
如果应用想要开启自启动,那么就要监听这个广播,程序启动之前,动态广播接收器肯定是无法使用的,我相信大家对此没有什么疑问
如果先接收到,那么程序就会先启动,至于先启动的优势,我想那些迫不及待的人比谁都清楚

接收顺序到底与什么有关,说实话,我也不清楚,不过先别急着拍我,我也不是完全不知道……
顺序与解析应用的顺序是一致的,但是解析应用的顺序是怎样的呢?
首先要告诉大家的是,这和你apk的文件名没有关系!

比如a.apk、b.apk两个应用,结果并不能保证a能比b先接收到,或者b能比a先接收到


然后告诉大家,这和apk的文件名有关系!

没错,但是为什么这么说?
用户安装一个应用有这么几个步骤

1下载一款应用,假设下载下来的时候这个应用叫new.apk
2安装。一般情况下,用户会在手机中操作,点击文件,然后系统会安装页面……然后大家都知道。另一种情况程序猿可能喜欢使用adb install -r new.apk

大家都知道,第三方应用会存放在/data/app目录下
当安装完毕之后,我们去这里看看,发现一个严峻的问题,那就是,你找不到一个叫new.apk的文件!
那你会找到什么?你会找到一个文件,他的名字是以与new.apk这个应用包名开始的,然后可能会跟着"-数字.apk",比如:com.android.test-1.apk


接收的顺序与这个名字是有关的!那么关系是怎样的呢?
系统在开机的时候,会按着一个顺序解析apk


1.首先,会解析手机中的/system/framework这个目录,原生系统中,这下面就一个apk - framework-res.apk
当然各个厂商也会加入自己的内容,比如我的这个目录下就有com.htc.resources.apk
2.然后受到重视的文件夹按顺序分别为:
/system/app
/vendor/app
/data/app
/drm/app-private

(代码分析在下一篇博客给出)

那么每个文件夹下解析的顺序是怎样的呢
我们先只看/data/app,也就是用户安装的第三方应用的存放位置

这与下面代码返回结果的顺序是一致的

File file = new File("/data/app/");
String[] files = file.list();

也就是说,我们按顺序打印这个数组,就能知道哪个接收器会先接收到这个广播,哪个会后接收到(为什么与这个结果一致,下篇文章分析)

(记住:本文默认说的这些接收器假设具有相同的优先级,如果优先级不同,当然是高优先级的先接收到)

现在大家可能有这么几个疑问:

1.String[] java.io.File.list(),这个函数的返回结果是怎样的顺序呢?

2.如何执行上面那段代码呢?

首先回答问题1

我不知道!

我们来看看javadoc给出的说明

javadoc 写道
There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order.

说的很清楚,人家不给你任何保证

听说在windows下执行的时候,结果会按着字母顺序排列,可惜,android是linux

但是我们可以耍赖,打印一下上面结果,如果自己的应用拍在后面,就改包名,直到你能排到前面,当然这不是什么好办法,但我也没有什么更好的办法了

现在回答问题2

执行这段代码需要root权限,因为一般应用是没有这个目录的读取权限的

如果手机没有root怎么办?你不会找一个root过的来查看结果吗……

我做了一个实验,我写了几个只有receiver的应用,把他们的包名分别设置为大家常用的、关系的应用包名

飞信:cn.com.fetion

LBE隐私卫士:com.lbe.security.lite

Handsent:com.handsent.nextsms

金山手机卫士:com.ijinshan.mguard

360手机卫士:com.qihoo360.mobilesafe

QQ手机管家:com.tencent.qqpimsecure

一个测试应用:com.example.boottest

File file = new File("/data/app/");
String[] files = file.list();
for (int i = ; i < files.length; i++) {
System.out.println("/data/app/:files["+(i+)+"]:" + files[i]);
}

结果为:

/data/app/:files[8]:com.tencent.qqpimsecure-1.apk

/data/app/:files[9]:com.qihoo360.mobilesafe-1.apk

/data/app/:files[10]:com.ijinshan.mguard-1.apk

/data/app/:files[11]:cn.com.fetion-1.apk

/data/app/:files[12]:com.lbe.security.lite-1.apk

/data/app/:files[13]:com.handsent.nextsms-1.apk

/data/app/:files[14]:com.example.boottest-1.apk

实际接收顺序为:

12-06 15:19:58.187: I/System.out(1880): getPackageName:com.tencent.qqpimsecure

12-06 15:19:58.288: I/System.out(1893): getPackageName:com.qihoo360.mobilesafe

12-06 15:19:58.378: I/System.out(1906): getPackageName:com.ijinshan.mguard

12-06 15:19:58.488: I/System.out(1920): getPackageName:cn.com.fetion

12-06 15:19:58.608: I/System.out(1933): getPackageName:com.lbe.security.lite

12-06 15:19:58.718: I/System.out(1946): getPackageName:com.handsent.nextsms

12-06 15:19:58.908: I/System.out(1959): getPackageName:com.example.boottest

如果其中一个优先级较高,比如cn.com.fetion,那么实际的接收顺序为

getPackageName:cn.com.fetion
getPackageName:com.tencent.qqpimsecure
getPackageName:com.qihoo360.mobilesafe
getPackageName:com.ijinshan.mguard
getPackageName:com.lbe.security.lite
getPackageName:com.handsent.nextsms
getPackageName:com.example.boottest

最后注意:

上面只是一个简单测试,并不是这些应用就是按着这个顺序,因为他们优先级也许不一致,也许在/data/app下的文件名不一致,导致顺序不一致

不过,看到这里,你应该知道如何去先于他们开机启动了

对于ROOT后的机器

留给大家一个问题,如果我是病毒,那我应该怎样去做呢?

显然,最理想的方式就是找个壳子应用,把实体病毒apk放到/system/framework目录中去,当然别忘了把自己的优先级设置成最高,不然也是白费

Android安全问题 抢先开机启动的更多相关文章

  1. Android安全问题 抢先接收广播 - 内因篇之广播接收器注册流程

    导读:本文说明系统是如何注册动态广播以及静态广播,这里主要注意其注册的顺序 这篇文章主要是针对我前两篇文章 android安全问题  抢先开机启动 - 结果篇 android安全问题  抢先拦截短信 ...

  2. Android安全问题 抢先接收广播 - 内因篇之广播发送流程

    导读:本文说明系统发送广播的部分流程,如何利用Intent查找到对应接收器.我们依然只关注接收器的排序问题 这篇文章主要是针对我前两篇文章 android安全问题(四) 抢先开机启动 - 结果篇 an ...

  3. Android安全问题 抢先拦截短信

    同上篇文章一样,这里只陈述结果,代码分析稍后给出 导读:本文叙述如何先于某些伪杀毒软件.病毒.常规软件获取到短信 众所周知,android系统在收到短信息的时候会发送广播,但是此广播是有序广播,也就是 ...

  4. Android如何获取开机启动项列表

    static final String BOOT_START_PERMISSION = "android.permission.RECEIVE_BOOT_COMPLETED"; p ...

  5. Android N 的开机启动流程概述

    原地址:https://blog.csdn.net/h655370/article/details/77727554 图片展示了Android的五层架构,从上到下依次是:应用层,应用框架层,库层,运行 ...

  6. Android——监听开机启动,自启动应用程序

    1.首先继承一个broadcastreceiver public class ConnectBroadCastReceiver extends BroadcastReceiver { @Overrid ...

  7. Android开机启动程序

    android程序实现开机启动的原理,简单点说就是做一个广播接收器,接收到开机广播时就启动activity或service或执行其它操作.Android系统在启动的时候会发出一个开机广播,内容为ACT ...

  8. Android开机启动Activity或者Service方法

    本文出自 “Bill_Hoo专栏” 博客,请务必保留此出处http://billhoo.blog.51cto.com/2337751/761230 这段时间在做Android的基础开发,现在有一需求是 ...

  9. Android 开机启动

    创建一个Receiver,用来监听开机完毕: public class MyReceiver extends BroadcastReceiver { static final String actio ...

随机推荐

  1. 使用WM_PASTE 和 WM_CHAR 消息时中文乱码总结

    当我们需要设置编辑框显示文本的时候,如果其它方式无法实现,可以试试WM_PASTE 和 WM_CHAR. 但使用这两种消息很容易出现中文乱码的情况,这一般是编码问题,可参考如下几点: 1,中文应采用U ...

  2. (hdu)5423 Rikka with Tree (dfs)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5423 Problem Description As we know, Rikka is p ...

  3. strlen() 和 strcpy()函数

    strlen() 和 strcpy()函数的区别,这两个一个是返回一个C风格字符串的长度,一个是对一个C风格字符串的拷贝,两个本来功能上是不同的,此外,他们还有一些细小的区别:strlen(" ...

  4. LINQ中实现 In 与 Not In

    T-SQL的IN: Select ProductID, ProductName, CategoryID From dbo.Products , ) T-SQL的NOT IN: Select Produ ...

  5. 关于mysql group_concat 不能显示为空的列的其他信息

    今天做项目遇到一个问题,百度好久都没找到问题所在 是酱紫的,一张表 关联的表 然后我用sql语句查询 point.pid,point.pname,GROUP_CONCAT(downsite.pname ...

  6. jQuery获取同级元素

    next()相邻下一个同级元素 prev()相邻上一个同级元素 siblings()所有同级元素 $("#id").next(); $("#id").prev( ...

  7. 一个汉字的ASCII编码&#12288;

    一个汉字的ASCII编码:  

  8. 在MVVMLight框架的ViewModel中实现NavigationService

    网上已经有很多方法了,比如通过Messenger来实现等等.这里我只讲述一种我比较喜欢的方法,因为它很方便 首先定义一个ViewModel基类,将所有ViewModel子类继承这个基类.在基类中定义 ...

  9. 地形图比例尺、等高距和DEM分辨率关系

    地表面的形态是很复杂的,不同地貌类型的形态是由它的相对高度、地面坡度以及所处的地势所决定的,它们是影响等高距的主要因素。从等高距计算公式可以看出,当地图比例尺和图上等高线间的最小距离简称等高线间距确定 ...

  10. oracle 多条执行语句同时执行

    oracle 多条执行语句同时执行:begin 语名一;语句二; end; 注意 如果写在C#里千万不要用@的方法然后语句里有回车 例: string strSql = "begin upd ...