Android Broadcast广播封装

news/2025/3/10 16:03:27/

在 Android 高版本(尤其是 Android 8.0 及以上)中,Broadcast 的使用受到了一些限制,例如 隐式广播 的限制和 后台执行限制。为了适配高版本并简化 Broadcast 的使用,可以封装一个工具类,支持动态注册、静态注册、权限控制等功能。

以下是 Broadcast 工具类的封装,支持高版本适配,并提供简洁的 API。

  1. Broadcast 工具类封装
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import androidx.annotation.RequiresApi;
import java.util.HashMap;
import java.util.Map;public class BroadcastUtils {private static final Map<Context, Map<BroadcastReceiver, IntentFilter>> receiverMap = new HashMap<>();/*** 动态注册广播** @param context  上下文* @param receiver 广播接收器* @param filter   意图过滤器*/public static void registerReceiver(Context context, BroadcastReceiver receiver, IntentFilter filter) {if (context == null || receiver == null || filter == null) {return;}// 高版本适配:使用 ContextCompat 注册if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {context.registerReceiver(receiver, filter, Context.RECEIVER_NOT_EXPORTED);} else {context.registerReceiver(receiver, filter);}// 保存注册信息,用于取消注册Map<BroadcastReceiver, IntentFilter> contextReceivers = receiverMap.get(context);if (contextReceivers == null) {contextReceivers = new HashMap<>();receiverMap.put(context, contextReceivers);}contextReceivers.put(receiver, filter);}/*** 取消注册广播** @param context  上下文* @param receiver 广播接收器*/public static void unregisterReceiver(Context context, BroadcastReceiver receiver) {if (context == null || receiver == null) {return;}try {context.unregisterReceiver(receiver);} catch (IllegalArgumentException e) {e.printStackTrace();}// 移除注册信息Map<BroadcastReceiver, IntentFilter> contextReceivers = receiverMap.get(context);if (contextReceivers != null) {contextReceivers.remove(receiver);if (contextReceivers.isEmpty()) {receiverMap.remove(context);}}}/*** 发送广播** @param context 上下文* @param intent  意图*/public static void sendBroadcast(Context context, Intent intent) {if (context == null || intent == null) {return;}context.sendBroadcast(intent);}/*** 发送带权限的广播** @param context      上下文* @param intent       意图* @param permission   权限*/public static void sendBroadcast(Context context, Intent intent, String permission) {if (context == null || intent == null || permission == null) {return;}context.sendBroadcast(intent, permission);}/*** 发送有序广播** @param context      上下文* @param intent       意图* @param permission   权限*/public static void sendOrderedBroadcast(Context context, Intent intent, String permission) {if (context == null || intent == null || permission == null) {return;}context.sendOrderedBroadcast(intent, permission);}/*** 取消注册所有广播** @param context 上下文*/public static void unregisterAllReceivers(Context context) {if (context == null) {return;}Map<BroadcastReceiver, IntentFilter> contextReceivers = receiverMap.get(context);if (contextReceivers != null) {for (BroadcastReceiver receiver : contextReceivers.keySet()) {try {context.unregisterReceiver(receiver);} catch (IllegalArgumentException e) {e.printStackTrace();}}contextReceivers.clear();receiverMap.remove(context);}}
}
  1. 使用示例
    2.1 动态注册广播
// 自定义广播接收器
BroadcastReceiver receiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {System.out.println("Device boot completed");}}
};// 注册广播
IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
BroadcastUtils.registerReceiver(context, receiver, filter);// 取消注册广播
BroadcastUtils.unregisterReceiver(context, receiver);

2.2 发送广播

// 发送普通广播
Intent intent = new Intent("com.example.CUSTOM_ACTION");
intent.putExtra("key", "value");
BroadcastUtils.sendBroadcast(context, intent);// 发送带权限的广播
String permission = "com.example.PERMISSION";
BroadcastUtils.sendBroadcast(context, intent, permission);

2.3 发送有序广播

// 发送有序广播
String permission = "com.example.PERMISSION";
BroadcastUtils.sendOrderedBroadcast(context, intent, permission);

2.4 取消注册所有广播

// 取消注册所有广播
BroadcastUtils.unregisterAllReceivers(context);
  1. 高版本适配说明
    3.1 隐式广播限制
    从 Android 8.0(API 26)开始,系统对 隐式广播 进行了限制。如果目标广播是隐式的,需要使用 显式广播 或 JobScheduler 替代。

3.2 后台执行限制
从 Android 9(API 28)开始,系统对后台应用的广播接收器进行了限制。如果应用在后台运行,某些广播可能无法接收。

3.3 动态注册
在高版本中,建议使用 动态注册 的方式注册广播接收器,并在适当的生命周期中取消注册,以避免内存泄漏。

  1. 静态注册广播
    如果需要在应用未启动时接收广播(如开机启动),可以使用 静态注册。以下是一个示例:

4.1 在 AndroidManifest.xml 中声明广播接收器

<receiver android:name=".MyBootReceiver"android:exported="true"android:permission="android.permission.RECEIVE_BOOT_COMPLETED"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter>
</receiver>

4.2 实现广播接收器

public class MyBootReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {System.out.println("Device boot completed");}}
}
5. 总结

通过封装 Broadcast 工具类,可以:

简化广播的注册和发送。

适配高版本的隐式广播限制。

支持权限控制和有序广播。

避免内存泄漏和重复注册。

建议将工具类封装到一个独立的模块中,方便在项目中复用。根据实际需求,可以进一步扩展功能,如支持跨进程广播、自定义权限等。


http://www.ppmy.cn/news/1578118.html

相关文章

星舰(Starship)近地轨道运力极限分析

SpaceX的星舰&#xff08;Starship&#xff09;作为下一代完全可重复使用的超重型运载系统&#xff0c;其近地轨道&#xff08;LEO&#xff09;极限运力的潜力备受关注。结合当前设计、技术演进路径和物理限制&#xff0c;未来星舰的LEO极限运力可能在以下范围内实现&#xff1…

机器学习12-视觉识别任务

机器学习12-视觉识别任务 分类语义分割滑动窗口滑动窗口的实现思路优点缺点现代替代方法 全卷积&#xff08;Fully Convolutional Networks, FCN&#xff09;FCN 的工作原理FCN 的性能优势FCN 的应用案例FCN 的局限性改进方向下采样可学习的上采样:转置卷积 目标检测区域建议Se…

耘锄、铧式犁、畦作

“耘锄”主要有以下含义&#xff1a; 农具名称 指用于除草和松土的锄头&#xff0c;常见于古代农业场景。例如唐代元稹诗句“种豆耘锄&#xff0c;种禾沟甽”即描述其使用场景1。这种农具现已逐渐退出历史舞台&#xff0c;但在传统农耕文化中仍有重要地位。 农业劳动 泛指田间…

Elastic:AI 会开始取代网络安全工作吗?

作者&#xff1a;来自 Elastic Joe DeFever 不会&#xff0c;但它正在从根本上改变这些工作。 生成式 AI (GenAI) 正迅速成为日常安全工作流程中的一个重要组成部分。那么&#xff0c;它是合作伙伴还是竞争对手&#xff1f; GenAI 技术在安全堆栈几乎每个方面的广泛应用&#…

【RK3588嵌入式图形编程】-SDL2-SDL_Image使用详解

SDL_Image使用详解 文章目录 SDL_Image使用详解1、概述2、初始化和退出 SDL_Image3、使用IMG_Load()4、透明度和混合模式5、透明度和像素格式6、保存图片7、总结在本文中,将介绍如何使用 SDL_Image 加载、操作和保存各种格式图像。 1、概述 在本文中,我们将开始使用之前安装…

Filebeat收集nginx日志到elasticsearch,最终在kibana做展示。

Filebeat收集nginx日志到elasticsearch&#xff0c;最终在kibana做展示。 项目需求是要将 一天或15分钟内 网站访问次数最多的10个IP 过滤出来&#xff0c;分析IP是否是攻击 EFK架构介绍 EFK三个开源软件组成&#xff0c;分别是Elasticsearch、FileBeat和Kibana。这三个软件…

docker 常用命令教程

文章目录 docker常用命令教程1. 镜像拉取镜像删除镜像查看镜像列表 2. 容器运行容器启动容器停止容器查看容器设置容器开机自启向容器输入命令 3. 镜像传输提交容器为镜像镜像解压缩登录命令推送远程仓库(需先在主机上登录账号) docker常用命令教程 1. 镜像 拉取镜像 docker…

电商项目-秒杀系统(四)秒杀异步下单防止重复秒杀

一、 防止恶意刷单解决 在生产场景下&#xff0c;可能会有一些人会恶意访问当前网站&#xff0c;来进行恶意的刷单。这样会造成当前系统出现一些业务上的业务混乱&#xff0c;出现脏数据&#xff0c;或者造成后端访问压力大等问题。 一般要解决这个问题的话&#xff0c;前端可…