android安全问题(七) 抢先接收广播

现在给出第二步分的分析

下面就来看看发送广播的流程

Context中的sendBroadCast函数的 实现是在ContextImpl中,和发送广播相关的有如下六个函数

void android.app.ContextImpl.sendBroadcast(Intent intent)

void android.app.ContextImpl.sendBroadcast(Intent intent, String receiverPermission)

void android.app.ContextImpl.sendOrderedBroadcast(Intent intent, String receiverPermission)

void android.app.ContextImpl.sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)

void android.app.ContextImpl.sendStickyBroadcast(Intent intent)

void android.app.ContextImpl.sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)

可以分为3组:1普通广播;2Ordered广播;3Sticky广播

不论哪种,最后都会 由ActivityManagerService处理

private final int broadcastIntentLocked(ProcessRecord 

callerApp,
        String callerPackage, Intent intent, String resolvedType,
        IIntentReceiver resultTo, int resultCode, String resultData,
        Bundle map, String requiredPermission,
        boolean ordered, boolean sticky, int callingPid, int callingUid)

以第一种情况为 例,流程图大概是这个样子的

ordered和sticky用来区分上面3组广播

下面我们仔细看看这个方 法都干了些什么

删减了一些代码

private final int broadcastIntentLocked

(ProcessRecord callerApp,
        String callerPackage, Intent intent, String resolvedType,
        IIntentReceiver resultTo, int resultCode, String resultData,
        Bundle map, String requiredPermission,
        boolean ordered, boolean sticky, int callingPid, int callingUid) {
    ...//处理特殊intent
    // Add to the sticky list if requested.
    ...//处理sticky广播
    // Figure out who all will receive this broadcast.
    List receivers = null;
    List<BroadcastFilter> registeredReceivers = null;
    try {
        if (intent.getComponent() != null) {
            // Broadcast is going to one specific receiver class...
            ActivityInfo ai = AppGlobals.getPackageManager().
                getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
            if (ai != null) {
                receivers = new ArrayList();
                ResolveInfo ri = new ResolveInfo();
                ri.activityInfo = ai;
                receivers.add(ri);
            }
        } else {
            // Need to resolve the intent to interested receivers...
            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
                     == 0) {
                receivers =
                    AppGlobals.getPackageManager().queryIntentReceivers(
                            intent, resolvedType, STOCK_PM_FLAGS);
            }
            registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
        }
    } catch (RemoteException ex) {
        // pm is in same process, this will never happen.
    }  

    final boolean replacePending =
            (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
    ...
    int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
    ...//如果广播是非ordered,先处理动态注册的接收器
    if (!ordered && NR > 0) {
        // If we are not serializing this broadcast, then send the
        // registered receivers separately so they don't wait for the
        // components to be launched.
        BroadcastRecord r = new BroadcastRecord(intent, callerApp,
                callerPackage, callingPid, callingUid, requiredPermission,
                registeredReceivers, resultTo, resultCode, resultData, map,
                ordered, sticky, false);
        ...
    //mParallelBroadcasts只含有动态注册的receiver
        boolean replaced = false;
        if (replacePending) {
            for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
                if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
                    if (DEBUG_BROADCAST) Slog.v(TAG,
                            "***** DROPPING PARALLEL: " + intent);
                    mParallelBroadcasts.set(i, r);
                    replaced = true;
                    break;
                }
            }
        }
        if (!replaced) {
            mParallelBroadcasts.add(r);
            scheduleBroadcastsLocked();
        }
        registeredReceivers = null;
        NR = 0;
    }  

    // Merge into one list.
    //如果广播是ordered,合并静态、动态接收器
    //否则之前处理过动态接收器,这里registeredReceivers为null
    int ir = 0;
    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);
            }
            //如果动态接收器优先级高,那么就插到前面
            //否则进入else,然后进行下一轮比较,拿下一个静态接收器与之前的动态接收器比较,直到找到自己的位置才插入进列表中
            //在这里,调整好接收器的顺序,同等优先级的,显然动态的要在静态的前面
            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;
            }
        }
    }
    while (ir < NR) {
        if (receivers == null) {
            receivers = new ArrayList();
        }
        receivers.add(registeredReceivers.get(ir));
        ir++;
    }  

    if ((receivers != null && receivers.size() > 0)
            || resultTo != null) {
        BroadcastRecord r = new BroadcastRecord(intent, callerApp,
                callerPackage, callingPid, callingUid, requiredPermission,
                receivers, resultTo, resultCode, resultData, map, ordered,
                sticky, false);
        ...
        if (!replaced) {
            mOrderedBroadcasts.add(r);
            scheduleBroadcastsLocked();
        }
    }  

    return BROADCAST_SUCCESS;
}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索string
, int
, 广播
, null
, android 广播
, intent
, 广播处理
, sticky
, Broadcast的接收
, received
, broadcast静态注册
, broadcast动态注册
, receive
receiver
android 接收广播、android 广播接收器、android 广播接收者、android广播接收不到、android 接收系统广播,以便于您获取更多的相关知识。

时间: 2024-08-30 01:45:35

android安全问题(七) 抢先接收广播的相关文章

android安全问题(六) 抢先接收广播

导读:本文说明系统是如何注册动态广播以及静态广播,这里主要注意其注册的顺序 这篇文章主 要是针对我前两篇文章 android安全问题(四) 抢先开机启动 - 结果篇 android安全问题(五 ) 抢先拦截短信 - 结果篇 之前只给出了结果,并没有给出代码分析,现在给出第一步分的分析 大家都知道,广播接收器分为动态注册和静态注册两种 静态接收,就是配置到manifest.xml文 件中,PackageManagerService扫描后记录其信息-- 动态接收,就是从代码中注册,通过调用下面的 方

Android中BroadcastReceiver(异步接收广播Intent)的使用_Android

Broadcast Receiver简介 Broadcast Receiver是Android的五大组件之一,使用频率也很高. 用于异步接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast().广播接收者(BroadcastReceiver)用于异步接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast().Context.sendOrderedBroadcast()或者Context.sendStickyBr

Android中BroadcastReceiver(异步接收广播Intent)的使用

Broadcast Receiver简介 Broadcast Receiver是Android的五大组件之一,使用频率也很高. 用于异步接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast().广播接收者(BroadcastReceiver)用于异步接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast().Context.sendOrderedBroadcast()或者Context.sendStickyBr

android安全问题(五) 抢先拦截短信

同上篇文章一样,这里只陈述结果,代码分析稍后给出 导读:本文叙述如何先于某些伪杀毒软件 .病毒.常规软件获取到短信 注意:如果你想抢先接收到短信,请务必阅读我上一篇文章,先要保证 你的应用最先开机启动 众所周知,android系统在收到短信息的时候会发送广播,但是此广播是有序广 播,也就是说:先接收到广播的人,如果心情不好,它就不会向后传递此广播,后面的人就不会知道有短信到 来 这与无序广播不同,无序广播并不是真的没有顺序(只是似乎大家习惯这么叫而已),无序广播的 接收者也是排队等待广播的,只不

Android——发送和接收广播

一,发送广播   利用Intent来发送广播. 使用:在需要发送广播的地方创建一个Intent对象,将信息的内容和用于过滤的信息封装起来,通过以下三种方法将Intent广播出去: 1,Context.sendBroadcast 2,Context.sendOrderedBroadCast 3,Context.sendStickyBroadcast   三种方法的区别: 1,sendBroadcast和sendStickyBroadcast发送出去的Intent,对于所有满足条件的Broadcas

android屏幕加解锁事件广播的监听

想在程序中监听屏幕SCREEN_ON和SCREEN_OFF这两个action,实现屏幕锁定状态的监听,从而实现自己的相应功能.比较奇怪的是这两个action只能通过代码的形式注册才能被监听到,在AndroidManifest.xml中注册根本监听不到.去网上查了一下,原来是PowerManager那边在发这个广播的时候做了限制,限制只有register到代码中的receiver才能接收.特此记录! public class ScreenActionReceiver extends Broadca

Android之Broadcast, BroadcastReceiver(广播)

Android之Broadcast, BroadcastReceiver(广播) 在 Android 中使用 Activity, Service, Broadcast, BroadcastReceiver 活动(Activity) - 用于表现功能 服务(Service) - 相当于后台运行的 Activity 广播(Broadcast) - 用于发送广播 广播接收器(BroadcastReceiver) - 用于接收广播 Intent - 用于连接以上各个组件,并在其间传递消息 =======

udp-PC端用UDP组播文件,android上如何来接收到该文件

问题描述 PC端用UDP组播文件,android上如何来接收到该文件 如题所说,我在PC端用工具将.zip升级包通过命令的方式广播出来,我的android盒子端如何去接收到升级包文件,又如何判断包的完整性 解决方案 http://blog.csdn.net/cuiran/article/details/40558085

android安全问题(三) 钓鱼程序

这个话题是继续android安全问题(二) 程序锁延伸的 之前我已经展示了如何制作程序锁.当打 开指定应用的时候,弹出一个密码页面. 程序锁的话题虽然是和安全相关,但是这应该属于防范的范 围,如果被人恶意利用,那么后果-- 这期我来揭示一下一种钓鱼程序的原理,希望广大用户不要上 当受骗,最主要的是:希望大家意识到安全问 之前我用定时扫描activity的方法来检查打开的页面是 不是我们所需要的页面 ComponentName topActivity = mActivityManager.getR