Android V 广播注册和配置注意事项问题

ops/2024/10/25 8:28:57/

现象

在Android V平台上,应用注册非Protected广播时,如果没有加导出flag会抛出异常导致进程crash。

E/AndroidRuntime: FATAL EXCEPTION: main

        java.lang.SecurityException: com.demo.myapplication: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts

                at android.os.Parcel.createExceptionOrNull(Parcel.java:3057)

官方的protected-broadcast参考

AndroidManifest.xml - OpenGrok cross reference for /frameworks/base/core/res/AndroidManifest.xml (aospxref.com)

平台规则

在Android 13 或更高版本为目标平台的应用内,在调用registerReceiver()时必须指定导出行为(exported true or false),如果未指定导出行为,可能会导致应用崩溃。

android:exported="true"

参考:广播概览  |  Background work  |  Android Developers

代码实现

接收广播

应用可以通过两种方式接收广播:通过清单声明的接收器 和上下文注册的接收器

1、【静态】声明广播接收器

1、指定 <receiver> 元素。

<!-- If this receiver listens for broadcasts sent from the system or fromother apps, even other apps that you own, set android:exported to "true". -->
<receiver android:name=".MyBroadcastReceiver" android:exported="false"><intent-filter><action android:name="APP_SPECIFIC_BROADCAST" /></intent-filter>
</receiver>

intent 过滤器指定您的接收器所订阅的广播操作。 

2、创建 BroadcastReceiver 子类并实现 onReceive(Context, Intent)。通过 以下示例中的广播接收器会记录日志并显示内容 以下内容:

public class MyBroadcastReceiver extends BroadcastReceiver {private static final String TAG = "MyBroadcastReceiver";@Overridepublic void onReceive(Context context, Intent intent) {StringBuilder sb = new StringBuilder();sb.append("Action: " + intent.getAction() + "\n");sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");String log = sb.toString();Log.d(TAG, log);ActivityNameBinding binding =ActivityNameBinding.inflate(layoutInflater);val view = binding.root;setContentView(view);Snackbar.make(view, log, Snackbar.LENGTH_LONG).show();}}

系统软件包管理器会在应用安装时注册接收器。 然后,接收器将成为应用的单独入口点,这意味着 确保系统可以启动应用并传递广播(如果应用未 。

系统会创建一个新的 BroadcastReceiver 组件 对象来处理它接收的每个广播。仅此对象有效 在调用 onReceive(Context, Intent) 期间有效。将代码添加到 返回时,系统会将该组件 活动状态。

2、【动态】上下文注册的接收器(常用)

上下文注册的接收器可以接收广播,前提是它们的注册 上下文有效。例如,如果您在一个 Activity 上下文,只要 activity 不被销毁,您就会收到广播。如果您 注册到应用上下文,那么,只要应用 正在运行。

先创建 BroadcastReceiver和IntentFilter,再通过调用registerReceiver()方法来注册接收器
 

RECEIVER_EXPORTED 导出flag定义

源码:

Context.java - OpenGrok cross reference for /frameworks/base/core/java/android/content/Context.java (aospxref.com)

    /*** <p>For apps targeting {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},* either {@link #RECEIVER_EXPORTED} or {@link #RECEIVER_NOT_EXPORTED} must be* specified if the receiver is not being registered for <a* href="{@docRoot}guide/components/broadcasts#system-broadcasts">system broadcasts</a>* or a {@link SecurityException} will be thrown. See {@link* #registerReceiver(BroadcastReceiver, IntentFilter, int)} to register a receiver with* flags.*//*** Flag for {@link #registerReceiver}: The receiver can receive broadcasts from other Apps.* Has the same behavior as marking a statically registered receiver with "exported=true"*/public static final int RECEIVER_EXPORTED = 0x2;/*** @deprecated Use {@link #RECEIVER_NOT_EXPORTED} or {@link #RECEIVER_EXPORTED} instead.* @hide*/@Deprecated@TestApipublic static final int RECEIVER_EXPORTED_UNAUDITED = RECEIVER_EXPORTED;/*** Flag for {@link #registerReceiver}: The receiver cannot receive broadcasts from other Apps.* Has the same behavior as marking a statically registered receiver with "exported=false"*/public static final int RECEIVER_NOT_EXPORTED = 0x4;

整改方案※

运行时注册的广播接收器必须指定导出行为。

1、查看服务或应用内是否注册动态广播,且该广播属于非Procted系统广播

protected-broadcast

2、按照监听情况,在调用registerReceiver时添加标志位参数RECEIVER_EXPORTED 或RECEIVER_NOT_EXPORTED

//RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTEDBroadcastReceiver br = new MyBroadcastReceiver();//系统广播
//写法1
//IntentFilter filter = new IntentFilter();
//filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);//写法2
//IntentFilter intentFilter = new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
//registerReceiver(mSimStateReceiver, intentFilter);//写法3:自定义
IntentFilter filter = new IntentFilter("com.demo.myintentfilter");
boolean isListenBroadcaseFromOtherAps = false;int receiverFlags;
if (isListenBroadcaseFromOtherAps) {receiverFlags = RECEIVER_EXPORTED;
} else {receiverFlags = RECEIVER_NOT_EXPORTED;
}ContextCompat.registerReceiver(context, br, filter, receiverFlags)

源码kotlin参考:

 源码Java参考:

ScreenshotHelper.java - OpenGrok cross reference for /frameworks/base/core/java/com/android/internal/util/ScreenshotHelper.java (aospxref.com)

    public ScreenshotHelper(Context context) {mContext = context;IntentFilter filter = new IntentFilter(ACTION_USER_SWITCHED);mContext.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_EXPORTED);}

如上参考:Android 14 之 动态注册Broadcast必须声明exported属性以 Android 14 为目标并动态 - 掘金 (juejin.cn)


http://www.ppmy.cn/ops/111295.html

相关文章

HarmonyOS开发之模拟器地图点击无效问题

问题描述 当我们模拟器已经运行了&#xff0c;但是需求中需要引用地图&#xff0c;地图的点击事件无效&#xff0c;模拟器地图点击事件以及地拖拖拽无效&#xff0c;这个时候需要配置一下通过 chrome://inspect/#devices 通常用于远程调试移动设备上的 Chrome 浏览器 1、先配…

如何搭建一个ip池用来做数据抓取用

在当今的数据驱动时代&#xff0c;数据抓取成为了获取网络信息的重要手段。然而&#xff0c;频繁的数据抓取活动可能会触发网站的安全机制&#xff0c;导致IP被封禁。为了维持数据抓取的持续性和稳定性&#xff0c;构建一个有效的IP池变得至关重要。本文将详细介绍如何搭建一个…

如何利用UML进行领域建模

如何利用UML进行领域建模 领域建模是通过创建抽象模型来反映业务领域中的核心概念、实体及其之间的关系。UML&#xff08;统一建模语言&#xff09;是进行领域建模的常用工具&#xff0c;它能帮助我们可视化地设计系统架构和业务逻辑。在这篇讲解中&#xff0c;我们将详细解释…

引领智能家居新风尚,WTN6040F门铃解决方案——让家的呼唤更动听

在追求高效与便捷的智能家居时代&#xff0c;每一个细节都承载着我们对美好生活的向往。WTN6040F&#xff0c;作为一款专为现代家庭设计的低成本、高性能门铃解决方案&#xff0c;正以其独特的魅力&#xff0c;悄然改变着我们的居家生活体验。 芯片功能特点&#xff1a; 1.2.4…

1658.将x减到0的最小操作数

题目 链接&#xff1a;leetcode链接 思路分析&#xff08;滑动窗口&#xff09; 题目要求从最左边或者最右边移除元素&#xff0c;需要思考两侧&#xff0c;这是比较麻烦的。 正难则反&#xff0c;我们逆向思维一下&#xff0c;最后剩余的元素是不是中间的连续区间&#xf…

MongoDB设置系统服务启动教程

1、编辑mongodb.service文件 将MongoDB设置成系统服务&#xff0c;就可以通过systemctl进行启动停止重启&#xff0c;在目录/etc/systemd/system下编写mongodb.service文件&#xff1a; [Unit] DescriptionMongoDB Database Server Documentationhttps://www.mongodb.com/docs…

nlohmann::json中有中文时调用dump转string抛出异常的问题

问题描述 Winodows下C开发想使用一个json库&#xff0c;使用的nlohmann::json&#xff0c;但是遇到json中使用中文时&#xff0c;转成string&#xff0c;会抛出异常。 nlohmann::json contentJson;contentJson["chinese"] "哈哈哈";std::string test con…

IP core 在硬件上实现的流程

IP&#xff08;Intellectual Property&#xff0c;知识产权核&#xff09; 最终会通过硬件实现&#xff0c;集成到实际的芯片或系统中。IP 核本质上是设计好的电路或逻辑单元&#xff0c;经过授权后由芯片制造商将其集成到更大的系统级芯片&#xff08;SoC&#xff09;、微控制…