ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android中的BroadcastReceiver

2020-12-05 13:31:47  阅读:254  来源: 互联网

标签:接收 MyReceiver 广播 intent 开机 Android BroadcastReceiver


目录

注:本文中代码部分使用Kotlin语言进行编写

一、介绍

广播分为两个方面: 广播发送者和广播接收者(BroadcastReceiver)
广播类型:
1. 标准广播(normal broadcasts): 是一种完全异步执行的广播,在广播发出去之后,所有的BroadcastReceiver几乎会在同一时刻收到这条广播。所以对于BroadcastReceiver来说它们没有顺序可言。这种广播效率高,但也无法被截断。
2. 有序广播(ordered broadcasts): 同步执行广播,在广播发出去之后同一时刻只会有一个BroadcastReceiver接收到广播,当这个BroadcastReceiver中的逻辑执行完之后才会继续传递。所以,对于BroadcastReceiver来说是有先后顺序之分的,优先级高的BroadcastReceiver先接受到广播,优先级低的BroadcastReceiver后接收到广播,并且BroadcastReceiver还可以截断广播,使优先级低于当前BroadcastReceiver的BroadcastReceiver无法接收到广播。
使用场景:
同一app内部的同一组件内的消息通信(单个或多个线程之间)
同一app内部的不同组件之间的消息通信(单个进程)
同一app具有多个进程的不同组件之间的消息通信
不同app之间的组件之间消息通信Android系统在特定情况下与App之间的消息通信。

二、简单使用

BroadcastReceiver在使用时要先进行注册,注册BroadcastReceiver的方式一般分为静态注册(在AndroidManifest.xml中注册)、动态注册(在代码中注册)。静态注册可以让程序在未启动的状态下也能接收广播,而动态注册则只能在程序启动之后才能接收广播。

2.1 静态广播

以接收开机广播为例

新建BroadcastReceiver,右键点击含有主类的包,New->Other->Broadcast Receiver,
在这里插入图片描述
在新建的BroadcastReceiver中编写逻辑

class MyReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        
        Toast.makeText(context,"成功接收开机广播",Toast.LENGTH_LONG).show()
        
    }
}

注:BroadcastReceiver中是不允许开启线程的,当onReceive()方法运行较长时间时,程序会报错,不建议添加过多的逻辑及耗时间的操作

AndroidManifest.xml中注册,其中enabled属性表示表示是否启用这个BroadcastReceiver,exported属性表示是否允许BroadcastReceiver接收本程序外的广播

 <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
</receiver>

receiver标签中添加一个intent-filter标签,使BroadcastReceiver可以接受开机广播

 <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

为了保证用户隐私,接收开机广播需要使用系统权限,在AndroidManifest.xml中声明系统权限(在application上方声明)

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

2.2 自定义广播

2.2.1 标准广播

创建一个BroadcastReceiver来接收广播,参考上述静态广播中的创建方法

class MyReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {

        Toast.makeText(context,"成功接收开机广播",Toast.LENGTH_LONG).show()

    }
}

receiver标签中添加一个intent-filter标签,使BroadcastReceiver可以接受自定义广播广播

 <intent-filter>
                <action android:name="com.example.broadcastreceviertext.MY_BROADCAST"/>
            </intent-filter>

activity_main.xml中添加代码,创建一个按钮作为触发点

<Button
		android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="BUTTON"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

给按钮设置点击监听事件

button.setOnClickListener { 
			//新建一个Intent对象,并将要发送的广播的值传入
            val intent = Intent("com.example.broadcastreceviertext.MY_BROADCAST")
            //将当前应用程序的包名传给intent
            intent.setPackage(packageName)
            //发送广播
            sendBroadcast(intent)		
        }

注:Android8.0系统之后,静态注册的BroadcastReceiver是无法接受隐式广播的,默认情况下我们创建的自定义广播均为隐式广播,所以要调用setPackage()方法指定广播要发给那个应用程序,从而将广播设置为显式广播

运行程序,点击按钮即可发送广播,在BroadcastReceiver接受到广播时将会执行我们编写的逻辑Toast.makeText(context,"成功接收开机广播",Toast.LENGTH_LONG).show()

由于广播是使用Intent来发送的,所以我们还可以在发送广播的同时携带数据传递给相应的BroadcastReceiver

2.2.2 有序广播

有序广播式一种同步执行广播,并且可以被截断
再创建一个BroadcastReceiver,新建MyReceiver_2

class MyReceiver_2 : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context,"MyReceiver_2成功接收开机广播", Toast.LENGTH_LONG).show()
    }
}

修改AndroidManifest.xml中代码,使两个BroadcastReceiver监听同一条广播

<receiver
            android:name=".MyReceiver_2"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.broadcastreceviertext.MY_BROADCAST" />
            </intent-filter>
        </receiver>

**运行程序可以看到分别弹出两条提示信息

成功接收开机广播
MyReceiver_2成功接收开机广播

修改按钮监听事件的代码

button.setOnClickListener { 
			//新建一个Intent对象,并将要发送的广播的值传入
            val intent = Intent("com.example.broadcastreceviertext.MY_BROADCAST")
            //将当前应用程序的包名传给intent
            intent.setPackage(packageName)
            //发送有序广播
             sendOrderedBroadcast(intent,null)		
        }

添加代码android:priority="100",将MyReceiver的优先级设置为100,保证MyReceiver的优先级高于MyReceiver_2

<receiver
            android:name=".MyReceiver_2"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.broadcastreceviertext.MY_BROADCAST" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter  android:priority="100">
                <action android:name="com.example.broadcastreceviertext.MY_BROADCAST" />
            </intent-filter>
        </receiver>

修改 MyReceiver中的代码,将广播截断

class MyReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {

        Toast.makeText(context,"MyReceiver成功接收开机广播",Toast.LENGTH_LONG).show()
		//将广播截断
		abortBroadcast()
    }
}

运行程序可以看到只会弹出MyReceiver中设置的提示信息

成功接收开机广播

使用sendOrderedBroadcast()方法,将广播设置为有序广播,并且MyReceiver的优先级比MyReceiver_2高,所以MyReceiver先接收到广播,MyReceiver_2后接收广播,但是MyReceiver中使用abortBroadcast()方法将广播截断,所以MyReceiver_2无法接收到广播

标签:接收,MyReceiver,广播,intent,开机,Android,BroadcastReceiver
来源: https://blog.csdn.net/Ternence_T/article/details/110518275

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有