当前位置: 首页 > article >正文

安卓广播的使用

广播(Broadcast)

广播(Broadcast)是 Android 系统用于应用间通信的一种机制,它可以用于系统与应用之间,或应用与应用之间的消息传递。比如,当设备电量不足、网络连接发生变化、时间变更等,系统会通过广播通知所有感兴趣的应用。广播机制使得应用可以在不相互依赖的情况下进行消息交互。所以广播算是一种进程通信机制。

广播的使用场景

系统事件广播:Android 系统会发送许多广播,比如设备启动、电量变化、Wi-Fi 连接状态等。这些广播可以帮助应用感知系统环境的变化。

应用自定义广播:应用也可以发送自定义广播,用于内部的组件之间通信。例如,当某个操作完成后,通知其他组件做出相应响应。

工作原理

广播的基本工作原理是由发送方发送广播,系统会自动将广播传递给相应的接收方。

  • 发送广播:任何应用或系统事件都可以发送广播,比如网络状态变化、电池电量变化等。
  • 接收广播:应用需要通过注册广播接收器(BroadcastReceiver)来接收这些广播。

广播可以分为两大类:

  1. 标准广播(Normal Broadcast):
    • 广播是完全异步的,所有接收者几乎在同一时间接收广播,广播接收器之间没有顺序。
    • 通常这种广播效率较高,但无法进行有序的广播传递。
  1. 有序广播(Ordered Broadcast):
    • 广播是同步的,可以按照优先级传递消息,广播接收器根据其优先级顺序依次接收广播。
    • 每个接收者都可以决定是否将广播传递给下一个接收者,也可以对广播进行修改。

广播的使用

  1. 创建广播接收器BroadcastReceiver

实现BroadcastReceiver 类并在清单中注册,以此来接收广播。当接收到广播时,系统会自动调用 onReceive() 方法:

public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 处理接收到的广播信息,这里是主线程可以用来更新UI,但不能做耗时操作 String action = intent.getAction(); if (action != null) { switch (action) { case Intent.ACTION_BATTERY_LOW: // 电量不足时的处理逻辑 break; case Intent.ACTION_BOOT_COMPLETED: // 开机完成时的处理逻辑 break; // 处理其他广播 } } } }

注册广播接收器

  1. 静态注册: 通过 AndroidManifest.xml 注册。这种方式广播接收器始终在后台等待广播,广播不依赖于某个Context上下文。只要应用进程存在即可。注意:在Android8.0以上,出于性能和安全性的考虑,有了限制后台执行的机制,而且版本越高,限制越多。有很多系统广播事件都不再允许使用静态注册,所以建议优先使用动态注册。

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

  1. 动态注册(推荐): 在代码中通过 Context.registerReceiver() 动态注册。这种方式灵活性更高,但接收器仅在应用运行时生效。广播依赖于某个Activity或者是Service上下文。上下文被销毁,那就无法收到广播。

//在onCreate或者onStart中注册广播监听 MyBroadcastReceiver receiver = new MyBroadcastReceiver(); IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_LOW); registerReceiver(receiver, filter); //在onDestory或者onStop中注销广播监听 unregisterReceiver(receiver);

MyBroadcastReceiver中重写onReceive方法,一旦系统发出通知,onReceive就会被触发

public class MyBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "MyBroadcastReceiver"; @Override public void onReceive(Context context, Intent intent) { // 处理接收到的广播信息 String action = intent.getAction(); if (action != null) { switch (action) { case Intent.ACTION_SCREEN_OFF: Log.i(TAG, "onReceive: 屏幕关闭!"); break; case Intent.ACTION_SCREEN_ON: Log.i(TAG, "onReceive: 屏幕点亮!"); break; // 处理其他广播 } } } }

常见的系统广播事件

系统广播(System Broadcast)是一种常见的机制,用于通知应用程序某些系统状态的变化。因为Android系统不同版本,对不同的广播事件使用规范也不一样,所以在使用广播的时候,需要注意权限以及系统版本升级带来的变化,以下是一些常见的系统广播事件:

  1. 设备启动完成(BOOT_COMPLETED)
  • 描述:当设备启动完成且所有系统组件已加载时,系统会发出该广播,应用可以在接收到这个广播后执行初始化操作。需要声明权限 android.permission.RECEIVE_BOOT_COMPLETED。
  • 用例:应用程序可以在设备启动时启动一些后台任务或服务。

<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

  1. 网络连接状态变化(CONNECTIVITY_CHANGE)
  • 描述:当设备的网络连接状态发生变化时(如 Wi-Fi 连接、移动数据连接状态变化),系统会发出该广播。
  • 用例:应用可以通过这个广播检测网络是否可用,从而调整网络请求策略。

IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(new MyBroadcastReceiver(), filter);

  1. 电量过低(ACTION_BATTERY_LOW)
  • 描述:当设备电池电量过低时,系统会发出此广播,通常是为了提示用户节约电量或采取节电措施。
  • 用例:应用可以在接收到该广播时降低资源消耗,暂停非必要任务。

<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.BATTERY_LOW" /> </intent-filter> </receiver>

  1. 电池状态变化(BATTERY_CHANGED)
  • 描述:设备电池状态发生任何变化时(电量、电压、温度等),系统会发出该广播。这个广播是黏性广播。
  • 用例:应用可以通过这个广播了解设备的电池使用情况,采取相应的节电措施。

IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); registerReceiver(new MyBroadcastReceiver(), filter);

  1. 屏幕解锁(USER_PRESENT)
  • 描述:当设备的屏幕被解锁时,系统发出该广播。
  • 用例:应用可以在屏幕解锁后执行某些操作,比如恢复暂停的任务。

<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.USER_PRESENT" /> </intent-filter> </receiver>

  1. 时区变化(TIMEZONE_CHANGED)
  • 描述:当设备的时区发生变化时,系统会发出该广播。
  • 用例:当应用依赖于设备的时区信息时,接收到此广播可以相应调整时间显示。

<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.TIMEZONE_CHANGED" /> </intent-filter> </receiver>

  1. 时间变化(TIME_CHANGED)
  • 描述:当设备的时间设置被用户手动更改时,系统会发出该广播。
  • 用例:应用可以在接收到该广播时更新时间相关的显示或处理逻辑。

<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.TIME_SET" /> </intent-filter> </receiver>

  1. 媒体插入(MEDIA_MOUNTED)
  • 描述:当外部存储(如 SD 卡)插入并且可以使用时,系统会发出该广播。
  • 需要权限。android.permission.READ_EXTERNAL_STORAGE 和android.permission.WRITE_EXTERNAL_STORAGE。
  • 用例:当用户插入 SD 卡时,应用可以扫描媒体文件或准备使用外部存储进行数据操作。

<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.MEDIA_MOUNTED" /> <data android:scheme="file" /> </intent-filter> </receiver> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

  1. 飞行模式变化(AIRPLANE_MODE)
  • 描述:当设备进入或退出飞行模式时,系统会发出该广播。
  • 用例:应用可以在飞行模式切换时调整网络相关的操作,或者提醒用户当前设备没有网络连接。

<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.AIRPLANE_MODE" /> </intent-filter> </receiver>

  1. 应用安装/删除(PACKAGE_ADDED / PACKAGE_REMOVED)
  • 描述:当有应用被安装或删除时,系统会发出这些广播。需要权限 android.permission.QUERY_ALL_PACKAGES。
  • 用例:应用可以根据接收到的安装或删除广播动态调整某些功能或配置。

<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.PACKAGE_ADDED" /> <action android:name="android.intent.action.PACKAGE_REMOVED" /> <data android:scheme="package" /> </intent-filter> </receiver> <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

  1. 屏幕关闭(SCREEN_OFF)
  • 描述:当设备的屏幕关闭(即用户按下电源键或系统熄屏时),系统会发出该广播。
  • 用例:应用可以在屏幕关闭时暂停某些耗电操作,例如停止动画或暂停视频播放。

<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.SCREEN_OFF" /> </intent-filter> </receiver>

  1. 屏幕点亮(SCREEN_ON)
  • 描述:当设备的屏幕点亮时,系统会发出该广播。
  • 用例:应用可以在屏幕点亮时恢复暂停的任务或刷新数据。

<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.SCREEN_ON" /> </intent-filter> </receiver>

  1. 设备锁屏(ACTION_USER_PRESENT)
  • 描述:当用户解锁屏幕时,系统会发出该广播,通常可以与 SCREEN_ON 配合使用。
  • 用例:应用可以在接收到该广播后恢复任务,或解锁时执行某些操作。

<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.USER_PRESENT" /> </intent-filter> </receiver>

自定义广播的使用

前面学习的都是系统的应用或者进程发出来的系统广播事件,但在开发中,我们也会借住广播实现很多自定义的广播事件。比如用户登录、注销后,会进行APP内的通知,告诉一些对登录状态感兴趣的页面,用户已经变更了登录状态。

  1. 发送自定义广播

// 在状态发生变化的地方发送广播 Intent intent = new Intent(); intent.setAction("com.ls.test.loginstatus");//自定义规则建议:前面包名+自定义事件名 intent.putExtra("key_islogin", true);//通知用户已登录 sendBroadcast(intent);

  1. 创建一个继承自 BroadcastReceiver 的类,并重写 onReceive 方法。

在LoginStatusReceiver的onReceive中捕获事件,并且获取传递过来的参数,然后做出业务处理

public class LoginStatusReceiver extends BroadcastReceiver { private static final String TAG = "LoginStatusReceiver"; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals("com.ls.test.loginstatus")) { boolean islogin = intent.getBooleanExtra("key_islogin", false); Log.i(TAG, "onReceive: loginstatus islogin = " + islogin); } } }

  1. 注册广播接收器
  • 建议使用动态注册的形式:

LoginStatusReceiver statusReceiver = new LoginStatusReceiver(); //自定义广播注册接收器,需要在第三个参数指定是否允许外部APP进程触发: //RECEIVER_EXPORTED表示允许 RECEIVER_NOT_EXPORTED表示不允许 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { registerReceiver(statusReceiver, new IntentFilter("com.ls.test.loginstatus"), Context.RECEIVER_EXPORTED); }

  • 也可以在清单中注册:

<receiver android:name=".LoginStatusReceiver" android:exported="false"> <intent-filter> <action android:name="com.ls.test.loginstatus" /> </intent-filter> </receiver>

有序广播

前面我们使用的sendBroadcast最长被用到,是向注册过广播的接收方统一发送广播,不会考虑接收顺序,被称为“无序广播”。但有时候我们还会使用sendOrderedBroadcast发送有序广播。具体做法如下:

  1. 注册接收器:为接收器设置priority优先级,数字越大越,优先级越高,可以早点收到广播:

statusReceiver = new LoginStatusReceiver(); IntentFilter filter = new IntentFilter("com.example.javatestproject.loginstatus"); filter.setPriority(100);//数字越大,优先级越高 registerReceiver(statusReceiver, filter, Context.RECEIVER_EXPORTED);

静态注册:

<receiver android:name=".MyOrderedBroadcastReceiver1"> <intent-filter android:priority="100"> <action android:name="com.example.orderedbroadcast"/> </intent-filter> </receiver> <receiver android:name=".MyOrderedBroadcastReceiver2"> <intent-filter android:priority="50"> <action android:name="com.example.orderedbroadcast"/> </intent-filter> </receiver>

  1. 发送有序广播:

sendOrderedBroadcast(intent,null);

适用场景

  • 在系统级别的事件处理中,有序广播可以用来确保重要的系统组件或者具有高权限的应用先处理事件。例如,当设备的电池电量发生变化时,系统可能会发送一个有序广播。系统的核心电源管理服务可以设置较高的优先级来首先接收这个广播,进行电量统计等关键操作。如果电量过低,它可以截断广播,防止一些不必要的电池消耗行为。
  • 应用层的场景:有序广播可以用于模块之间的协作。例如,一个具有登录模块、数据同步模块和界面显示模块的应用。当用户登录成功后,可以发送一个有序广播,登录模块设置较高优先级先对用户信息进行本地存储等操作,然后数据同步模块可以接收到广播并开始同步数据,最后界面显示模块接收到广播更新界面显示用户已登录状态。

http://www.kler.cn/a/572465.html

相关文章:

  • Elasticsearch:简化大数据分析,使用Elasticsearch进行高效数据聚合
  • LeetCode hot 100—轮转数组
  • visual studio 2022 手工写一个简单的MFC程序
  • [原创](Modern C++)现代C++的关键性概念: 什么是友元函数, 什么是友元类?
  • css不出现滚动条
  • T-SQL 语言基础: SQL 数据库对象元数据及配置信息获取
  • 计算机网络——子网掩码
  • 网络安全中keli是什么
  • 初识Qt · 实现hello world的N种细节和对象树
  • Springboot快速接入Deepseek
  • 椭圆函数3D双重周期性交互式演示工具
  • 【hot100】102二叉树的层序遍历
  • 生态安全相关
  • Linux搜索---find
  • 【后端开发面试题】每日 3 题(六)
  • 使用ffmpeg读取mp4文件解码失败
  • Android+SpringBoot的老年人健康饮食小程序平台
  • 基于 Spring Boot 的企业级快速启动模板 —— spring-quick
  • 看视频学习方法总结
  • 知识图谱科研文献推荐系统vue+django+Neo4j的知识图谱