今天继续总结Android APP漏洞四大组件中Broadcast Recevier漏洞挖掘的知识,主要分为两个部分,一部分对Android 广播机制原理作一个初步的总结,另一部分便是对Android 广播机制常见的一些漏洞进行总结,主要是介绍一些已存在的典型漏洞,部分知识可以参考前两篇帖子Android APP漏洞之战(2)——Service漏洞挖掘详解和Android APP漏洞之战(1)——Activity漏洞挖掘详解。
Android的广播机制使用了设计模式中的观察者模式:基于消息的发布/订阅事件模型,从设计模式上讲,广播的发送者和接收者极大程度的**解耦**,使得系统方便集成,容易扩展
。
模型中的3个基本角色:
模型的具体原理如下图所示:
我们先通过一个流程图来具体的理解广播机制的运行原理:
具体的操作流程:
我们可以按照流程图具体一步步来实现广播机制:
<1>自定义广播接收者BroadcastReceiver:
<2>广播接收者注册:
注册的方式分为两种:静态注册、动态注册
静态注册:
注册方式:
属性说明:
具体实例:
我们完成静态注册后,当App首次启动时,系统会自动实例化mBroadcastReceiver类,并注册到系统中
动态注册:
注册方式:
具体实例:
具体实现步骤:
注意事项:
两种注册方式的对比:
这里我们就完成了广播接收者的基本工作
<3>广播发送者定义和发送广播:
广播的发送:
广播的类型:
第一种分类:
广播接收器一般可以分为两种类型:标准广播和有序广播
第二种分类:
普通广播:
开发者自身定义intent的广播(最常用),发送广播使用如下:
若被注册了的广播接收者中注册时intentFilter的action与上述匹配,则会接收此广播(即进行回调onReceive()),如下mBroadcastReceiver则会接收上述广播
如果发送的广播有对应权限,那么广播接收者也需要对应权限
系统广播:
Android中内置了多个系统广播:只要涉及到手机的基本操作(如开机、网络状态变化、拍照等),都会发送相应的广播每个广播都有特定的Intent-Filter(包括具体的action),Android系统广播action如下:
有序广播:
发送出去的广播被广播接收者按照先后顺序接收 有序是针对广播接收者而言的。广播接收者接收广播的顺序规则(同时面向静态和动态注册的广播接收者):
特点:
具体使用:有序广播的使用过程与普通广播非常类似,差异仅在于广播的发送方式
App应用内广播(Local Broadcast):本地广播
产生的原因:
实现步骤:
方法2的具体实现:
这里我们就完成了开发人员手动完成部分,就成功实现了Android的广播机制,后续就是系统自动完成了
最后我们关注一些不同注册方式的广播接收器回调onReceive()中的context返回值
Broadcast Reciver漏洞大致可以分为:
Broadcast Reciver漏洞的危害:
案例1:
我们发现一个目标程序段代码如下:
通过分析得出,该程序通过intent隐式传递,并通过action匹配发送一个广播,这样系统内其他程序都可以接收到这个广播,然后在广播接收者中编写接收代码,这样我们可以编写攻击代码获取敏感数据信息
我们就可以通过广播获取该程序的密码
修复:
我们尝试采用本地广播的方式,这样程序发出的广播就只能被app自身广播接收器接收
案例2:Android 操作系统中通过 RSSI 广播暴露敏感数据 (CVE-2018-9581)
漏洞详情:
攻击代码:
测试步骤:
我们可以利用广播接收者获取广播中的敏感信息RSSI值
案例1:小米MIUI漏洞可能导致硬件资源消耗
漏洞详情:
漏洞攻击代码:
我们这里就是通过intent隐私传递,发送广播,然后匹配小米应用中的action,这样就可以打开或广播手电筒,从而利用这个漏洞,导致系统电源迅速消耗
修复:
案例2:酷派最安全手机s6拨打电话权限绕过
漏洞详情:
攻击代码:
通过intent启动外部电话应用,匹配action,并授权标志位,这样就可以不用获取权限,就可以打电话
修复:
案例3:酷派最安全手机s6程序锁绕过
漏洞详情:
漏洞测试:
简单测试方法用adb shell 发送广播,用来解锁
然后使用命令行
就可以成功解锁:
修复:
案例1:百度云盘手机版钓鱼、信息泄露和代码执行高危漏洞三合一
漏洞描述:
攻击代码:
修复:
案例1:QQ手机管家拒绝服务漏洞
漏洞描述:
攻击代码:
案例2:fourgoats.apk拒绝服务攻击崩溃
我们首先用drozer测试可导出组件
我们根据组件的类名找对对应的源码信息,发现需要两个参数 phoneNumber、message:
我们发送恶意广播:
在此之前,我们在AndroidManifest.xml文件里面获取广播名:
我们发送恶意广播:
可以发现我们恶意广播发送成功
我们再向广播组件发送不完整intent,使用空 extras,可以看到应用停止运行:
我们就成功完成一次拒绝服务攻击
修复:
拒绝服务攻击可以参考Activity的拒绝服务攻击和Service的拒绝服务攻击
本文主要介绍了Android中广播机制的运行原理,并对Android广播机制中的常见漏洞做了一个初步的总结,我们可以发现Android的四大组件的漏洞原理基本存在很大的相关性,在拒绝服务攻击中,这里用了一个简易的样本,并逐步实现了拒绝服务攻击的步骤,本文可能还存在很多不足,后续逐步完善,也欢迎各位大佬指正。
github首页:github
Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序只会收到自己所关心的广播内容,这些广播可以是来自系统的,也可能是来自其他程序的。Android提供了一套完整的API,允许应用程序自由地发送和接收广播。
广播机制分为两个方面:广播发送者和广播接收者,一般来说,BroadcastReceiver就是广播接收者。
Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序只会收到自己所关心的广播内容,这些广播可以是来自系统的,也可能是来自其他程序的。Android提供了一套完整的API,允许应用程序自由地发送和接收广播。
广播机制分为两个方面:广播发送者和广播接收者,一般来说,BroadcastReceiver就是广播接收者。
(
1
)Android内不同组件间的通信(应用
/
不同应用之间)
(
2
)多线程通信
(
3
)与Android系统在特定情况下的通信
(
1
)Android内不同组件间的通信(应用
/
不同应用之间)
(
2
)多线程通信
(
3
)与Android系统在特定情况下的通信
(
1
)消息订阅者(广播接收者)
(
2
)消息发布者(广播发布者)
(
3
)消息中心(AMS,即Activity Manager Service)
(
1
)消息订阅者(广播接收者)
(
2
)消息发布者(广播发布者)
(
3
)消息中心(AMS,即Activity Manager Service)
(
1
)首先开发人员自定义广播接收者BroadcastReceiver,并重写onRecvice()方法,在里面可以实现具体操作,然后到消息中心AMS注册
(
2
)广播发送者定义并向AMS发送广播
(
3
)AMS查找符合相应条件(IntentFilter
/
Permission等)的BroadcastReceiver
(
4
)AMS将广播发送到上述符合条件的BroadcastReceiver相应的消息循环队列中
(
5
)BroadcastReceiver通过消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。
(
1
)首先开发人员自定义广播接收者BroadcastReceiver,并重写onRecvice()方法,在里面可以实现具体操作,然后到消息中心AMS注册
(
2
)广播发送者定义并向AMS发送广播
(
3
)AMS查找符合相应条件(IntentFilter
/
Permission等)的BroadcastReceiver
(
4
)AMS将广播发送到上述符合条件的BroadcastReceiver相应的消息循环队列中
(
5
)BroadcastReceiver通过消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。
/
/
继承BroadcastReceivre类
public
class
mBroadcastReceiver extends BroadcastReceiver {
/
/
复写onReceive()方法
/
/
接收到广播后,则自动调用该方法
@Override
public void onReceive(Context context, Intent intent) {
/
/
写入接收广播后的操作
}
}
/
/
继承BroadcastReceivre类
public
class
mBroadcastReceiver extends BroadcastReceiver {
/
/
复写onReceive()方法
/
/
接收到广播后,则自动调用该方法
@Override
public void onReceive(Context context, Intent intent) {
/
/
写入接收广播后的操作
}
}
操作步骤:
(
1
)继承BroadcastReceivre基类
(
2
)必须复写抽象方法onReceive()方法
广播接收器接收到相应广播后,会自动回调 onReceive() 方法,一般情况下,onReceive方法会涉及 与 其他组件之间的交互,如发送Notification、启动Service等,默认情况下,广播接收器运行在 UI 线程,因此,onReceive()方法不能执行耗时操作,否则将导致ANR
操作步骤:
(
1
)继承BroadcastReceivre基类
(
2
)必须复写抽象方法onReceive()方法
广播接收器接收到相应广播后,会自动回调 onReceive() 方法,一般情况下,onReceive方法会涉及 与 其他组件之间的交互,如发送Notification、启动Service等,默认情况下,广播接收器运行在 UI 线程,因此,onReceive()方法不能执行耗时操作,否则将导致ANR
在AndroidManifest.xml里通过<receive>标签声明
在AndroidManifest.xml里通过<receive>标签声明
<receiver
android:enabled
=
[
"true"
|
"false"
]
/
/
此broadcastReceiver能否接收其他App的发出的广播
/
/
默认值是由receiver中有无intent
-
filter
决定的:如果有intent
-
filter
,默认值为true,否则为false
android:exported
=
[
"true"
|
"false"
]
android:icon
=
"drawable resource"
android:label
=
"string resource"
/
/
继承BroadcastReceiver子类的类名
android:name
=
".mBroadcastReceiver"
/
/
具有相应权限的广播发送者发送的广播才能被此BroadcastReceiver所接收;
android:permission
=
"string"
/
/
BroadcastReceiver运行所处的进程
/
/
默认为app的进程,可以指定独立的进程
/
/
注:Android四大基本组件都可以通过此属性指定自己的独立进程
android:process
=
"string"
>
/
/
用于指定此广播接收器将接收的广播类型
/
/
本示例中给出的是用于接收网络状态改变时发出的广播
<intent
-
filter
>
<action android:name
=
"android.net.conn.CONNECTIVITY_CHANGE"
/
>
<
/
intent
-
filter
>
<
/
receiver>
<receiver
android:enabled
=
[
"true"
|
"false"
]
/
/
此broadcastReceiver能否接收其他App的发出的广播
/
/
默认值是由receiver中有无intent
-
filter
决定的:如果有intent
-
filter
,默认值为true,否则为false
android:exported
=
[
"true"
|
"false"
]
android:icon
=
"drawable resource"
android:label
=
"string resource"
/
/
继承BroadcastReceiver子类的类名
android:name
=
".mBroadcastReceiver"
/
/
具有相应权限的广播发送者发送的广播才能被此BroadcastReceiver所接收;
android:permission
=
"string"
/
/
BroadcastReceiver运行所处的进程
/
/
默认为app的进程,可以指定独立的进程
/
/
注:Android四大基本组件都可以通过此属性指定自己的独立进程
android:process
=
"string"
>
/
/
用于指定此广播接收器将接收的广播类型
/
/
本示例中给出的是用于接收网络状态改变时发出的广播
<intent
-
filter
>
<action android:name
=
"android.net.conn.CONNECTIVITY_CHANGE"
/
>
<
/
intent
-
filter
>
<
/
receiver>
<receiver
/
/
此广播接收者类是mBroadcastReceiver
android:name
=
".mBroadcastReceiver"
>
/
/
用于接收网络状态改变时发出的广播
<intent
-
filter
>
<action android:name
=
"android.net.conn.CONNECTIVITY_CHANGE"
/
>
<
/
intent
-
filter
>
<
/
receiver>
<receiver
/
/
此广播接收者类是mBroadcastReceiver
android:name
=
".mBroadcastReceiver"
>
/
/
用于接收网络状态改变时发出的广播
<intent
-
filter
>
<action android:name
=
"android.net.conn.CONNECTIVITY_CHANGE"
/
>
<
/
intent
-
filter
>
<
/
receiver>
动态注册需要在功能代码中进行注册
(
1
)实例化自定义的广播接收者,我们实现广播的功能,可以继承BroadcastReceiver类,并重写类中的方法
(
2
)实例化意图过滤器,并设置要过滤的广播类型
(
3
)使用Context的registerReceiver(BroadcastReceiver,IntentFilter)方法注册广播
(
4
)在onDestory()方法中通过调用unregisterReceiver()方法来实现取消注册
(
1
)实例化自定义的广播接收者,我们实现广播的功能,可以继承BroadcastReceiver类,并重写类中的方法
(
2
)实例化意图过滤器,并设置要过滤的广播类型
(
3
)使用Context的registerReceiver(BroadcastReceiver,IntentFilter)方法注册广播
(
4
)在onDestory()方法中通过调用unregisterReceiver()方法来实现取消注册
注意:动态广播最好在Activity的onResume()注册、onPause()注销
原因:
1.
对于动态广播,有注册就必然得有注销,否则会导致内存泄露
2.Activity
生命周期如下都是成对出现的 onCreate() & onDestory()、onStart() & onStop()、onResume() & onPause()
在onResume()注册、onPause()注销是因为onPause()在App死亡前一定会被执行,从而保证广播在App死亡前一定会被注销,从而防止内存泄露。
(
1
)不在onCreate() & onDestory() 或 onStart() & onStop()注册、注销是因为:当系统因为内存不足(优先级更高的应用需要内存,请看上图红框)要回收Activity占用的资源时,Activity在执行完onPause()方法后就会被销毁,有些生命周期方法onStop(),onDestory()就不会执行。当再回到此Activity时,是从onCreate方法开始执行。
(
2
)假设我们将广播的注销放在onStop(),onDestory()方法里的话,有可能在Activity被销毁后还未执行onStop(),onDestory()方法,即广播仍还未注销,从而导致内存泄露。
(
3
)但是,onPause()一定会被执行,从而保证了广播在App死亡前一定会被注销,从而防止内存泄露。
注意:动态广播最好在Activity的onResume()注册、onPause()注销
原因:
1.
对于动态广播,有注册就必然得有注销,否则会导致内存泄露
2.Activity
生命周期如下都是成对出现的 onCreate() & onDestory()、onStart() & onStop()、onResume() & onPause()
在onResume()注册、onPause()注销是因为onPause()在App死亡前一定会被执行,从而保证广播在App死亡前一定会被注销,从而防止内存泄露。
(
1
)不在onCreate() & onDestory() 或 onStart() & onStop()注册、注销是因为:当系统因为内存不足(优先级更高的应用需要内存,请看上图红框)要回收Activity占用的资源时,Activity在执行完onPause()方法后就会被销毁,有些生命周期方法onStop(),onDestory()就不会执行。当再回到此Activity时,是从onCreate方法开始执行。
(
2
)假设我们将广播的注销放在onStop(),onDestory()方法里的话,有可能在Activity被销毁后还未执行onStop(),onDestory()方法,即广播仍还未注销,从而导致内存泄露。
(
3
)但是,onPause()一定会被执行,从而保证了广播在App死亡前一定会被注销,从而防止内存泄露。
(
1
)广播 是 用意图(Intent)标识
(
2
)定义广播的本质
=
定义广播所具备的“意图(Intent)
(
3
)广播发送
=
广播发送者 将此广播的“意图(Intent)”通过sendBroadcast()方法发送出去
(
1
)广播 是 用意图(Intent)标识
(
2
)定义广播的本质
=
定义广播所具备的“意图(Intent)
(
3
)广播发送
=
广播发送者 将此广播的“意图(Intent)”通过sendBroadcast()方法发送出去
标准广播:一种完全异步执行的广播,广播发出之后,所有的广播接收器都会在同一时刻接收这条广播信息,广播效率比较高,同时是无法截断的。
标准广播:一种完全异步执行的广播,广播发出之后,所有的广播接收器都会在同一时刻接收这条广播信息,广播效率比较高,同时是无法截断的。
有序广播:是一种同步执行的广播,在广播发出之后,同一时刻会有一个广播接收器能收到这条广播消息,当这个广播接收器中逻辑执行完毕后,广播才会继续传递。
有序广播:是一种同步执行的广播,在广播发出之后,同一时刻会有一个广播接收器能收到这条广播消息,当这个广播接收器中逻辑执行完毕后,广播才会继续传递。
广播的类型主要分为
5
类:
(
1
)普通广播
(
2
)系统广播
(
3
)有序广播
(
4
)粘性广播
(
5
)App应用内广播
广播的类型主要分为
5
类:
(
1
)普通广播
(
2
)系统广播
(
3
)有序广播
(
4
)粘性广播
(
5
)App应用内广播
Intent intent
=
new Intent();
/
/
对应BroadcastReceiver中intentFilter的action
intent.setAction(
"BROADCAST_ACTION"
);
/
/
发送广播
sendBroadcast(intent);
Intent intent
=
new Intent();
/
/
对应BroadcastReceiver中intentFilter的action
intent.setAction(
"BROADCAST_ACTION"
);
/
/
发送广播
sendBroadcast(intent);
<receiver
/
/
此广播接收者类是mBroadcastReceiver
android:name
=
".mBroadcastReceiver"
>
/
/
用于接收网络状态改变时发出的广播
<intent
-
filter
>
<action android:name
=
"BROADCAST_ACTION"
/
>
<
/
intent
-
filter
>
<
/
receiver>
<receiver
/
/
此广播接收者类是mBroadcastReceiver
android:name
=
".mBroadcastReceiver"
>
/
/
用于接收网络状态改变时发出的广播
<intent
-
filter
>
<action android:name
=
"BROADCAST_ACTION"
/
>
<
/
intent
-
filter
>
<
/
receiver>
系统操作 action
监听网络变化 android.net.conn.CONNECTIVITY_CHANGE
关闭或打开飞行模式 Intent.ACTION_AIRPLANE_MODE_CHANGED
充电时或电量发生变化 Intent.ACTION_BATTERY_CHANGED
电池电量低 Intent.ACTION_BATTERY_LOW
电池电量充足(即从电量低变化到饱满时会发出广播 Intent.ACTION_BATTERY_OKAY
系统启动完成后(仅广播一次) Intent.ACTION_BOOT_COMPLETED
按下照相时的拍照按键(硬件按键)时 Intent.ACTION_CAMERA_BUTTON
屏幕锁屏 Intent.ACTION_CLOSE_SYSTEM_DIALOGS
设备当前设置被改变时(界面语言、设备方向等) Intent.ACTION_CONFIGURATION_CHANGED
插入耳机时 Intent.ACTION_HEADSET_PLUG
未正确移除SD卡但已取出来时(正确移除方法:设置
-
-
SD卡和设备内存
-
-
卸载SD卡) Intent.ACTION_MEDIA_BAD_REMOVAL
插入外部储存装置(如SD卡) Intent.ACTION_MEDIA_CHECKING
成功安装APK Intent.ACTION_PACKAGE_ADDED
成功删除APK Intent.ACTION_PACKAGE_REMOVED
重启设备 Intent.ACTION_REBOOT
屏幕被关闭 Intent.ACTION_SCREEN_OFF
屏幕被打开 Intent.ACTION_SCREEN_ON
关闭系统时 Intent.ACTION_SHUTDOWN
重启设备 Intent.ACTION_REBOOT
注:当使用系统广播是,只需要在注册广播接收者时定义相关的action即可,并不需要手动发送广播,当系统有相关操作时会自动进行系统广播
系统操作 action
监听网络变化 android.net.conn.CONNECTIVITY_CHANGE
关闭或打开飞行模式 Intent.ACTION_AIRPLANE_MODE_CHANGED
充电时或电量发生变化 Intent.ACTION_BATTERY_CHANGED
电池电量低 Intent.ACTION_BATTERY_LOW
电池电量充足(即从电量低变化到饱满时会发出广播 Intent.ACTION_BATTERY_OKAY
系统启动完成后(仅广播一次) Intent.ACTION_BOOT_COMPLETED
按下照相时的拍照按键(硬件按键)时 Intent.ACTION_CAMERA_BUTTON
屏幕锁屏 Intent.ACTION_CLOSE_SYSTEM_DIALOGS
设备当前设置被改变时(界面语言、设备方向等) Intent.ACTION_CONFIGURATION_CHANGED
插入耳机时 Intent.ACTION_HEADSET_PLUG
未正确移除SD卡但已取出来时(正确移除方法:设置
-
-
SD卡和设备内存
-
-
卸载SD卡) Intent.ACTION_MEDIA_BAD_REMOVAL
插入外部储存装置(如SD卡) Intent.ACTION_MEDIA_CHECKING
成功安装APK Intent.ACTION_PACKAGE_ADDED
成功删除APK Intent.ACTION_PACKAGE_REMOVED
重启设备 Intent.ACTION_REBOOT
屏幕被关闭 Intent.ACTION_SCREEN_OFF
屏幕被打开 Intent.ACTION_SCREEN_ON
关闭系统时 Intent.ACTION_SHUTDOWN
重启设备 Intent.ACTION_REBOOT
注:当使用系统广播是,只需要在注册广播接收者时定义相关的action即可,并不需要手动发送广播,当系统有相关操作时会自动进行系统广播
(
1
)按照Priority属性值从大
-
小排序
(
2
)Priority属性相同者,动态注册的广播优先
(
1
)按照Priority属性值从大
-
小排序
(
2
)Priority属性相同者,动态注册的广播优先
(
1
)接收广播按顺序接收
(
2
)先接收的广播接收者可以对广播进行截断,即后接收的广播接收者不在接收此广播,可以使用abortBroadcast()方法
(
3
)先接收的广播接收者可以对广播进行修改,那么后接收的广播接收者将接收到被修改后的广播
(
1
)接收广播按顺序接收
(
2
)先接收的广播接收者可以对广播进行截断,即后接收的广播接收者不在接收此广播,可以使用abortBroadcast()方法
(
3
)先接收的广播接收者可以对广播进行修改,那么后接收的广播接收者将接收到被修改后的广播
sendOrderedBroadcast(intent,null);
/
/
参数
1
:接收的Intent 参数
2
:与权限相关字符串,一般为null
sendOrderedBroadcast(intent,null);
/
/
参数
1
:接收的Intent 参数
2
:与权限相关字符串,一般为null
由于Android中的广播可以跨App直接通信(exported对于有intent
-
filter
情况下默认值为true)
导致可能会出现的问题:
(
1
)其他App针对性发出与当前App intent
-
filter
相匹配的广播,由此导致当前App不断接收广播并处理
(
2
)其他App注册与当前App一致的intent
-
filter
用于接收广播,获取广播的具体星系,会出现安全性和效率性问题
解决方案:
使用App应用内广播(Local Broadcast)
(
1
)App应用内广播壳理解为一种局部广播,广播的发送者和接收者都同属于一个App
(
2
)相比于全局广播(普通广播),App应用内广播优势体现在:安全性高和效率高
由于Android中的广播可以跨App直接通信(exported对于有intent
-
filter
情况下默认值为true)
导致可能会出现的问题:
(
1
)其他App针对性发出与当前App intent
-
filter
相匹配的广播,由此导致当前App不断接收广播并处理
(
2
)其他App注册与当前App一致的intent
-
filter
用于接收广播,获取广播的具体星系,会出现安全性和效率性问题
解决方案:
使用App应用内广播(Local Broadcast)
(
1
)App应用内广播壳理解为一种局部广播,广播的发送者和接收者都同属于一个App
(
2
)相比于全局广播(普通广播),App应用内广播优势体现在:安全性高和效率高
方法
1
:
将全局广播设置为局部广播
(
1
)注册广播是将exported属性设置为false,使得非本App内部发出的此广播不被接收
(
2
)在广播的发送和接收时,增设相应权限permission,用于权限验证
(
3
)发送广播时指定该广播接收器所在的包名,此广播将只会发送到此包中的App内与之相匹配的有效广播接收器中
通过intent.setPackage(packageName)指定包名
方法
2
:
使用封装好的LocalBroadcastManager类使用方式上与全局广播几乎相同,只是注册
/
取消注册广播接收器和发送广播时将参数context变成LocalBroadcastManager的单一实例。
注意:对于LocalBroadcastManager方式发送的应用内广播,只能通过LocalBroadcastManager动态注册,不能静态注册
方法
1
:
将全局广播设置为局部广播
(
1
)注册广播是将exported属性设置为false,使得非本App内部发出的此广播不被接收
(
2
)在广播的发送和接收时,增设相应权限permission,用于权限验证
(
3
)发送广播时指定该广播接收器所在的包名,此广播将只会发送到此包中的App内与之相匹配的有效广播接收器中
通过intent.setPackage(packageName)指定包名
方法
2
:
使用封装好的LocalBroadcastManager类使用方式上与全局广播几乎相同,只是注册
/
取消注册广播接收器和发送广播时将参数context变成LocalBroadcastManager的单一实例。
注意:对于LocalBroadcastManager方式发送的应用内广播,只能通过LocalBroadcastManager动态注册,不能静态注册
/
/
注册应用内广播接收器
/
/
步骤
1
:实例化BroadcastReceiver子类 & IntentFilter mBroadcastReceiver
mBroadcastReceiver
=
new mBroadcastReceiver();
IntentFilter intentFilter
=
new IntentFilter();
/
/
步骤
2
:实例化LocalBroadcastManager的实例
localBroadcastManager
=
LocalBroadcastManager.getInstance(this);
/
/
步骤
3
:设置接收广播的类型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
/
/
步骤
4
:调用LocalBroadcastManager单一实例的registerReceiver()方法进行动态注册
localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);
/
/
取消注册应用内广播接收器
localBroadcastManager.unregisterReceiver(mBroadcastReceiver);
/
/
发送应用内广播
Intent intent
=
new Intent();
intent.setAction(BROADCAST_ACTION);
localBroadcastManager.sendBroadcast(intent);
/
/
注册应用内广播接收器
/
/
步骤
1
:实例化BroadcastReceiver子类 & IntentFilter mBroadcastReceiver
mBroadcastReceiver
=
new mBroadcastReceiver();
IntentFilter intentFilter
=
new IntentFilter();
/
/
步骤
2
:实例化LocalBroadcastManager的实例
localBroadcastManager
=
LocalBroadcastManager.getInstance(this);
/
/
步骤
3
:设置接收广播的类型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
/
/
步骤
4
:调用LocalBroadcastManager单一实例的registerReceiver()方法进行动态注册
localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);
/
/
取消注册应用内广播接收器
localBroadcastManager.unregisterReceiver(mBroadcastReceiver);
/
/
发送应用内广播
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-4-12 17:05
被随风而行aa编辑
,原因: