Broadcast专讲

0. 前言

最近遇到一个问题,在做培训时,屡试不爽的广播消息竟然存在接收不到广播的情况。经了解后发现,Android O 已对隐式广播添加限制。so,下面总结下 Android 中广播相关。

1. 广播注册

广播注册分为静态注册和动态注册,静态注册的广播,可以在程序没被启动时,接收到全局广播消息。而动态注册广播,只有在程序启动后接收广播消息。

1.1 静态注册

定义好广播消息后,在 AndroidManife.xml 中注册即可,示例中,添加多个 Action。

<receiver
    android:name="com.flueky.demo.DemoReceiver"
    android:permission="com.flueky.demo.permission.Demo_Receiver">
    <intent-filter android:priority="999">
        <action android:name="com.flueky.app.Demo_Receiver" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.flueky.demo.TEST_RECEIVER1" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.flueky.demo.TEST_RECEIVER2" />
    </intent-filter>
</receiver>

1.2 动态注册

动态注册指在 Activity 或 Service 中注册,并在 Activity 或 Service 销毁时,需要注销。

// 注册广播
registerReceiver(testReceiver, new IntentFilter("com.flueky.demo.TEST_RECEIVER1"));
// 注销广播
unregisterReceiver(testReceiver);

由于动态注册的广播可以通过定义内部类的方式实现,因此,动态 注册的广播可以同宿主 Activity 或 Service 进行交互。

2. 广播分类

2.1 无序广播

应用发出广播后,所有注册了广播 Action 接收到广播的先后顺序是未知的,则叫发送了无序广播。

Intent intent = new Intent("com.flueky.app.Demo_Receiver");
sendBroadcast(intent, "com.flueky.demo.permission.Demo_Receiver");

2.2 有序广播

应用发出广播后,所有注册了广播 Action 接收到广播的先后顺序是固定的,则叫发送了无序广播。

Intent intent = new Intent("com.flueky.app.Demo_Receiver");
sendOrderedBroadcast(intent, "com.flueky.demo.permission.Demo_Receiver");
  1. 发送有序广播需要指定一个权限。
  2. 优先级高的接收器,优先接收到消息,并可以像优先级低的广播传递数据,还可以终止广播继续传递。
<!--定义优先级-->
<intent-filter android:priority="999">
    <action android:name="com.flueky.app.Demo_Receiver" />
</intent-filter>

有序广播接收器中传递消息和终止广播如下:

//非有序广播,不不做下面的操作
if (!isOrderedBroadcast())
    return;
// 获取前一个广播传递的消息 
Bundle bundle = getResultExtras(true);
String received = bundle.getString("received");

Log.d(TAG, "onReceive: 广播发送 "+(received==null?"null":received));

// 将消息传递给下一个待接收的广播。
bundle.putString("received","已被 send 接收");
setResultExtras(bundle);
// 终止广播
abortBroadcast();

2.3 本地广播

发送有序广播和无序广播后,设备中的其他应用只需要注册了接收广播的 Action ,都可以接收到广播消息。为了只在自己应用中接收到广播消息,Google 先后给出了两种方案。其中一种是本地广播,通过 v4 包提供了 LocalBroadcastManager 类,注册、注销和发送广播。

// 注册本地广播
LocalBroadcastManager.getInstance(this).registerReceiver(testReceiver, new IntentFilter("com.flueky.demo.TEST_RECEIVER2"));
// 发送本地广播
LocalBroadcastManager.getInstance(this).sendBr
oadcast(new Intent("com.flueky.demo.TEST_RECEIVER2"));
// 注销本地广播
LocalBroadcastManager.getInstance(this).unregisterReceiver(testReceiver);

本地广播只能通过动态注册的方式,而且由 LocalBroadcastManager 注册的广播只能接收 LocalBroadcastManager 发送的广播。

3. 自定义权限

在 Android 8.0 以上,使用全局广播必须给广播接收器添加上权限。发送广播时需要使用广播接收器申明的权限,而且,发送广播的应用需要在 AndroidManifest.xml 中申明权限。

具体做法是:发送广播的应用清单文件类容如下:

<!--定义一个权限-->
<permission
    android:name="com.flueky.demo.permission.Demo_Receiver"
    android:protectionLevel="signature" />

<!--申明使用这个权限-->
<uses-permission android:name="com.flueky.demo.permission.Demo_Receiver" />

代码如下:

// 发送带权限的广播,有序广播和无序广播都行。
Intent intent = new Intent("com.flueky.app.Demo_Receiver");
sendBroadcast(intent, "com.flueky.demo.permission.Demo_Receiver");

接收广播应用的清单文件如下:

<!--使用自定义的权限,包括下面注册广播时,使用的 permission 属性。-->
<uses-permission android:name="com.flueky.demo.permission.Demo_Receiver" />

<receiver
    android:name="com.flueky.demo.DemoReceiver"
    android:permission="com.flueky.demo.permission.Demo_Receiver">
    <intent-filter android:priority="1000">
        <action android:name="com.flueky.app.Demo_Receiver" />
    </intent-filter>
</receiver>

最后,发送广播和接收广播的应用必须使用同一个签名文件。因为自定义权限的安全级别是 signature

源码地址

觉得有用?那打赏一个呗。去打赏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值