广播机制

Android中的广播机制更加灵活:
因为Android中的每个应用都可以堆自己感兴趣的广播进行注册
这样该程序就只会收到自己关心的广播内容
这些广播可能是来自系统的,也可能是来自其他应用的
发送广播是通过intent
接受广播是通过BroadcastReveiver

广播分成两类:

  • 标准广播:完全异步执行,在广播发出之后,几乎所有broadcastReceiver会在同一时间收到这条广播消息,因此他们之间没有任何先后顺序可言,这种广播的效率比较高,但同时他也是无法被截断的
  • 有序广播:同步执行,广播发出之后,同样一时间只会有一个BroadcastReceiver能够接收到这条广播消息,当BroadcastReceiver中的逻辑执行完了之后,广播才会继续传递,此时的BroadcastReceiver是有先后顺序的,优先级高的会先收到广播消息,并且前面的BroadcastReceiver可以截断消息,这样后面的BroadcastReceiver就无法接收到广播消息了

接收系统广播

我们可以根据自己感兴趣的广播,自由的注册BroadcastReceiver这样相应的广播发出时候,就会有相应的BroadcastReceiver能够接收广播,并且可以在内部进行逻辑处理
注册BroadcastReceiver的方式

  • 在代码中动态注册
  • 在AdnroidManifest.xml中静态注册

动态广播

实践出真知class MainActivity : AppCompatActivity() {lateinit var timeChangeReceiver:TimeChangeReceiveroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)/*intent和intentFilter的区别后者比前者多了个筛选作用筛选条件:action、data和category*/val intentFilter=IntentFilter()//定义一个有过滤器的意图intentFilter.addAction("android.intent.action.TIME_TICK")//给意图添加一个筛选条件(筛选出Action是android.intent.action.TIME_TICK的意图)timeChangeReceiver=TimeChangeReceiver()//实例化一个时间改变广播接收器registerReceiver(timeChangeReceiver,intentFilter)//注册一个广播接收器timeChangeReveiver来监听intentFilter这个意图}override fun onDestroy() {super.onDestroy()//当这个活动销毁的时候就把接收器取消注册(一定要取消)unregisterReceiver(timeChangeReceiver)}inner class TimeChangeReceiver:BroadcastReceiver(){//定义一个接收器继承自BroadcastReceiver,override fun onReceive(context: Context, intent: Intent) {//当接收到一个消息就Toast一段话Toast.makeText(context,"Time Changed",Toast.LENGTH_LONG).show()}}
}

注册了注册一个广播接收器timeChangeReveiver来监听有这个动作(android.intent.action.TIME_TICK)的intentFilter这个意图,一旦时间过了一分钟广播接收器就会收到时间过了一分钟这个广播,然后Toast一句话

静态广播

  • 动态注册的广播接收器虽然可以自由的控制注册和注销,灵活性有优势,但是他只有在程序启动后才能接收广播.
  • 那么我们就可以用静态注册来在程序未启动的时候监听系统广播,但是这种方式给了恶意软件很大的操作空间,所以Android系统几乎每个版本都在削减静态注册的功能
  • 在Android8.0之后所有的隐式广播都不允许用讲堂注册的方式来接收了,隐式广播指的是那些没有具体指定发送给哪个应用程序的广播,大多数系统广播属于隐式广播,但是还有小部分的允许静态注册的方式接收小部分见官网
实践出真知新建一个Other->BroadcastReceiverclass BootCompleteReceiver : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent) {// This method is called when the BroadcastReceiver is receiving an Intent broadcast.Toast.makeText(context,"Boot Complete",Toast.LENGTH_LONG).show()/*但是注意在onReceive中不要使用太复杂的逻辑因为BroadcastReceiver中不允许开启线程当onReceive运行太久而没结束程序就会出现错误*/}}
静态注册还需要去AndroidManifest.xml中注册这个广播接收器并且声明他所需要的权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.bo.a6_learnbroadcastreceiver"><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><!--这里是声明这个Activity有android.permission.RECEIVE_BOOT_COMPLETED权限--><application···><!--android:name指定具体注册哪一个BroadcastReceiverandroid:enabled:是否启用这个广播接收器android:exported:是否允许接收本程序以外的广播--><receiverandroid:name=".BootCompleteReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /><!--只有行为是android.intent.action.BOOT_COMPLETED的意图才会被这个广播接收器接收--></intent-filter><receiverandroid:name=".BootCompleteReceiver"android:enabled="true"android:exported="true"><intent-filter><!--监听启动的时候--><action android:name="android.intent.action.BOOT_COMPLETED" /><!-- 只有行为是android.intent.action.BOOT_COMPLETED的意图才会被这个广播接收器接收 --></intent-filter><!--但是Android API Level8 以上的时候,程序可以安装在SD卡上。如果程序安装在SD卡上,那么在BOOT_COMPLETED广播发送之后,SD卡才会挂载,因此程序无法监听到该广播所以我么需要同时监听开机和sd卡挂载。(也不能只监听挂载就认为开机了,因为有的手机没有sd卡)--><intent-filter ><action android:name="android.intent.action.MEDIA_MOUNTED"/><action android:name="android.intent.action.MEDIA_UNMOUNTED"/><data android:scheme="file"></data></intent-filter></receiver></receiver>···</application></manifest>

遗憾的是我没有运行出效果,还不知道错误在哪里,希望以后能找出来
:我找到问题所在了哈哈哈哈:

  • Android API Level8 以上的时候,程序可以安装在SD卡上。如果程序安装在SD卡上,
  • 那么在BOOT_COMPLETED广播发送之后,SD卡才会挂载,因此程序无法监听到该广播
  • 所以我么需要同时监听开机和sd卡挂载。(也不能只监听挂载就认为开机了,因为有的手机没有sd卡)

发送自定义广播

发送标准广播

发送广播之前我们需要定义一个广播接收器来准备接收此广播

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.bo.a6_learnbroadcastreceiver">···<application···><receiverandroid:name=".MyBroadcastReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.bo.a6_learnbroadcastreceiver.MY_BROADCAST"/><!-- 告诉接收器我们待会接收到"com.bo.a6_learnbroadcastreceiver.MY_BROADCAST"这样一条广播--></intent-filter></receiver>···</application></manifest>
广播接收器接收后的执行逻辑
class MyBroadcastReceiver :BroadcastReceiver(){override fun onReceive(context: Context, intent: Intent) {Toast.makeText(context,"在定义的广播接收器中接收到了广播",Toast.LENGTH_LONG).show()}
}
activity_main.xml中
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"···>//定义一个按钮作为发出广播的触发点<Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/button"android:text="发送广播"/></LinearLayout>
按钮逻辑
class MainActivity : AppCompatActivity() {···override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)button.setOnClickListener {var intent=Intent("com.bo.a6_learnbroadcastreceiver.MY_BROADCAST")/*发出一条"com.bo.a6_learnbroadcastreceiver.MY_BROADCAST"这样的广播*/intent.setPackage(packageName)/*intent.setPackage至关重要,由于Android8.0之后无法静态注册隐式广播,但是我们的广播接收器就是静态注册的,而且默认情况下就是隐式广播所以我们要想办法把我们的广播变成显式广播,我们通过setPackage()指定了广播发给packageName,然后我们的广播就变成了显式广播*/sendBroadcast(intent)}···
}

这个倒是成功了

发送有序广播

与标准广播不同,有序广播是可以被截断的,而且是一种同步执行的广播
那么我们在创建一个广播接收器

我们可以再定义一个广播接收器class AnotherBroadcastReceiver : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent) {// This method is called when the BroadcastReceiver is receiving an Intent broadcast.Toast.makeText(context,"在另一个广播接收器中接收到了广播",Toast.LENGTH_LONG).show()}
}
并且注册<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"···>···<application···><receiverandroid:name=".AnotherBroadcastReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.bo.a6_learnbroadcastreceiver.MY_BROADCAST"/></intent-filter></receiver>···</application></manifest>

我们会发现点击按钮之后Toast出两句话,这是因为现在的广播还是标准广播,我们可以尝试改成有序广播

修改MainActivity.kt
class MainActivity : AppCompatActivity() {···override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)button.setOnClickListener {var intent=Intent("com.bo.a6_learnbroadcastreceiver.MY_BROADCAST")intent.setPackage(packageName)/*intent.setPackage至关重要,由于Android8.0之后无法静态注册隐式广播,但是我们的广播接收器就是静态注册的,而且默认情况下就是隐式广播所以我们要想办法把我们的广播变成显式广播,我们通过setPackage()指定了广播发给packageName,然后我们的广播就变成了显式广播*/sendOrderedBroadcast(intent,null)//发送广播的方式/*这里有两个参数,第一个是inent(广播的意图),第二个是权限(null就行)*/}···}···
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.bo.a6_learnbroadcastreceiver">···<application···><receiverandroid:name=".AnotherBroadcastReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.bo.a6_learnbroadcastreceiver.MY_BROADCAST"/></intent-filter></receiver>···<receiverandroid:name=".MyBroadcastReceiver"android:enabled="true"android:exported="true"><intent-filter android:priority="100"><action android:name="com.bo.a6_learnbroadcastreceiver.MY_BROADCAST" /><!-- 告诉接收器我们待会接收到"com.bo.a6_learnbroadcastreceiver.MY_BROADCAST"这样一条广播 --></intent-filter></receiver><!--<intent-filter android:priority="100"是设置这个接收器的优先级,优先级高的先收到 -->···</application></manifest>
class MyBroadcastReceiver :BroadcastReceiver(){override fun onReceive(context: Context, intent: Intent) {Toast.makeText(context,"在定义的广播接收器中接收到了广播",Toast.LENGTH_LONG).show()abortBroadcast()//表示将广播截断,后面的广播接收器就接收不到广播了}
}

发现只有一个Toast出来了

Demo:利用广播实现强制下线

t>

```kotlin
class MyBroadcastReceiver :BroadcastReceiver(){override fun onReceive(context: Context, intent: Intent) {Toast.makeText(context,"在定义的广播接收器中接收到了广播",Toast.LENGTH_LONG).show()abortBroadcast()//表示将广播截断,后面的广播接收器就接收不到广播了}
}

发现只有一个Toast出来了

Demo:利用广播实现强制下线

详情见项目

6-广播Broadcast相关推荐

  1. B08_NumPy 广播(Broadcast)

    NumPy 广播(Broadcast) 广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行. 如果两个数组 a 和 b ...

  2. Android中的广播Broadcast详解

    今天来看一下Android中的广播机制,我们知道广播Broadcast是Android中的四大组件之一,可见他的重要性了,当然它的用途也很大的,比如一些系统的广播:电量低.开机.锁屏等一些操作都会发送 ...

  3. Android 广播(Broadcast)

    Android 广播Broadcast 1.小声嘀咕 2.广播机制简介 3.接收系统广播 3.1动态注册 3.2静态注册 4.发送自定义广播 4.1标准广播 4.2有序广播 5.使用本地广播 1.小声 ...

  4. 无线广播(Broadcast)

    无线广播(Broadcast) Description A broadcaster wants to set up a radio broadcast transmitter in an area. ...

  5. 网络层:单播unicast 组播multicast 广播broadcast

    当前的网络中有三种通讯模式:单播.广播.组播(多播),其中的组播出现时间最晚但同时具备单播和广播的优点,最具有发展前景. 一.单播unicast: 主机之间"一对一"的通讯模式,网 ...

  6. NumPy 广播(Broadcast)与pandas基础知识

    文章目录 NumPy 广播(Broadcast) 控制遍历顺序 修改数组中元素的值 使用外部循环 广播迭代 Numpy 数组操作 修改数组形状 umpy.ndarray.flat umpy.ndarr ...

  7. 【Tsinghua】无线广播(broadcast)

    一个BFS. 无线广播(broadcast) 描述 某广播公司要在一个地区架设无线广播发射装置.该地区共有n个小镇,每个小镇都要安装一台发射机并播放各自的节目. 不过,该公司只获得了FM104.2和F ...

  8. 品茗论道说广播(Broadcast内部机制讲解)(上)

    品茗论道说广播(Broadcast内部机制讲解)(上) 侯 亮 1 概述 我们在编写Android程序时,常常会用到广播(Broadcast)机制.从易用性的角度来说,使用广播是非常简单的.不过,这个 ...

  9. PA7题解报告——无线广播(Broadcast)

    数据结构与算法实验2020夏第二批(中国石油大学) PA7题解报告--无线广播(Broadcast) 目录 题目描述 题目分析 编码实现 一.题目描述 1. 描述 某广播公司要在一个地区架设无线广播发 ...

  10. 无线广播(Broadcast)【1】

    无线广播(Broadcast) https://dsa.cs.tsinghua.edu.cn/oj/course.shtml?courseid=59 描述 某广播公司要在一个地区架设无线广播发射装置. ...

最新文章

  1. Android模拟器学framework和driver之传感器篇1(linux sensor driver)
  2. android运行过程简书,Android系统的启动流程
  3. 在Sun Enterprise Server上配置SCSI磁带机
  4. Linux驱动调试中的Debugfs的使用简介 CONFIG_DEBUG_FS 的功能与配置
  5. python手机端编程环境_移动端自动化测试解决方案(Appium + Python) - (1) 环境搭建...
  6. e.getMessage() e.printStackTrace() 和e.printStackTrace() 小结
  7. 剑指offer 重建二叉树
  8. Node js报错 npm ERR! cb() never called!
  9. Dancing Stars on Me HDU - 5533
  10. C++程序员必需的修养
  11. linux 查看手机硬件信息失败,linux下硬件信息的查看总结
  12. PrepareStatement对象(新增、删除、更新、查询、防止SQL注入)
  13. jQuery/CSS3炫酷动画效果插件 animate
  14. Windows Media Player单例模式
  15. 苹果有益让老iPhone变慢以迫使消费者购买新一代的iPhone?
  16. 锐捷长ping_【交换机】S8606--s5750E互连接口ping大包(length=18024)会丢包
  17. Modbus 与 RS485 的区别与联系
  18. 《Java性能调优实战》00丨开篇词丨怎样才能做好性能调优?2022.03.08-20220329学习完
  19. 上计算机课没有签到肿么办,钉钉教学直播如何课前签到 钉钉直播如何提醒未签到的学生...
  20. 华为、蚂蚁金服等都在招聘的大数据开发,需要具备哪些技能

热门文章

  1. 操作系统—物理内存与虚拟内存
  2. SMU激活函数讲解及代码实现
  3. 阿翔编程学-爱情感言
  4. CTF(信息安全夺旗赛)学习网址
  5. 【智慧农业】温室大棚控制系统如何解决管理粗放问题
  6. Android怎么自定义充电铃声,充电提示音怎么设置
  7. linux 软链接重新连接,Linux总结(十二)set_uid set_gid stic_bit 软链接 硬链接
  8. cadence SPB16.6原理图库(.olb)集合的库内容列表1
  9. RMC公链2022开启 坚持 共进与突破
  10. 第六届全国计算机学科博士后论坛,大会 | 「2018 第六届全国计算机学科博士后论坛」今天召开,鹏城实验室博士后工作站挂牌...