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

现象

在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 from
     other 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";
        @Override
        public 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
    @TestApi
    public 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_EXPORTED

BroadcastReceiver 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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/874349.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何用3个月零基础入门网络安全?_网络安全零基础怎么学习

前 言 写这篇教程的初衷是很多朋友都想了解如何入门/转行网络安全&#xff0c;实现自己的“黑客梦”。文章的宗旨是&#xff1a; 1.指出一些自学的误区 2.提供客观可行的学习表 3.推荐我认为适合小白学习的资源.大佬绕道哈&#xff01; →点击获取网络安全资料攻略← 一、自学…

k8s的配置管理

一、配置管理分为两种&#xff1a; 1. 加密配置&#xff1a;用来保存密码和token密钥对以及其它敏感的k8s资源。 2.应用配置&#xff1a;我们需要定制化的给应用进行配置&#xff0c;我们需要把定制好的配置文件同步到pod当中的容器。 二、加密配置 1.secret三种类型&#xf…

YOLOv8改进 | 模块缝合 | C2f 融合RVB + EMA注意力机制【二次融合 + 结构图】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

《垃圾回收的算法与实现》-算法-摘抄

本文是书籍《垃圾回收的算法与实现》的摘抄&#xff0c;不涉及算法源码及步骤讲解模块。 预备 对象由头(header)和域(field)构成。 头&#xff1a;对象中保存对象本身信息的部分&#xff0c;主要含有以下信息&#xff1a;对象的大小和种类。 域&#xff1a;对象使用者在对象…

图结构详解

概述 图是由有穷非空集合的顶点和顶点之间的边组成的集合&#xff0c;通常表示为 G(V,E)。G 表示一个图&#xff0c;V 是 图 G 顶点的集合&#xff0c;E 是图 G 边的集合。在图形结构中&#xff0c;数据之间具有任意联系&#xff0c;任意两个数据之间都可能相关&#xff0c;可…

彻底解决 node/npm, Electron下载失败相关问题, 从底层源码详解node electron 加速配置

最近玩了一下electron项目, 总是会遇到electron的下载失败问题, 于是看了一下node源码, 做一个记录. node/npm 加速配置 这个配置通过设置node配置里面的registry 这个配置项来完成加速. 配置方法 npm config set registry https://registry.npmmirror.com上面的命令就是将当…

打破界限,自闭症寄宿学校带给孩子的改变

在社会的广阔画卷中&#xff0c;有一群特别的孩子&#xff0c;他们以独特的视角感知世界&#xff0c;以非凡的方式表达情感&#xff0c;他们就是自闭症儿童。自闭症&#xff0c;这个听起来略带神秘色彩的词汇&#xff0c;实则承载着无数家庭的期盼与挑战。在这片充满爱的土地上…

C++设计模式——Iterator迭代器模式

一&#xff0c;迭代器模式的定义 迭代器模式是一种行为型设计模式&#xff0c;它使得遍历一个容器对象中的元素变得更加简单。 迭代器模式将遍历操作从容器对象&#xff08;如集合、列表&#xff09;中分离出来&#xff0c;它通过迭代器对象来遍历容器对象中的元素&#xff0…

RK3568平台开发系列讲解(PWM篇)使用 sysfs 接口操作 pwm

🚀返回专栏总目录 文章目录 一、查看 pwm 设备信息二、使用 sysfs 操作 PWM沉淀、分享、成长,让自己和他人都能有所收获!😄 PWM 子系统被划分为了三个层次, 分别为用户空间、 内核空间和硬件层, 内核空间包括 PWM 设备驱动层、 PWM 核心层和 PWM 适配器驱动层 一、查看…

JS面试真题 part3

JS面试真题 part3 11、bind、call、apply区别&#xff1f;如何实现一个bind12、JavaScript中执行上下文和执行栈是什么13、说说JavaScript中的事件模型14、解释下什么是事件代理&#xff1f;应用场景&#xff1f;15、说说你对闭包的理解&#xff1f;闭包使用场景 11、bind、cal…

分布式技术概览

文章目录 分布式技术1. 分布式数据库&#xff08;Distributed Databases&#xff09;2. 分布式文件系统&#xff08;Distributed File Systems&#xff09;3. 分布式哈希表&#xff08;Distributed Hash Tables, DHTs&#xff09;4. 分布式缓存&#xff08;Distributed Caching…

面向对象需求分析

1. 面向对象分析概述 1.1 面向对象基本概念 以对象为中心&#xff0c;以类为构造机制&#xff0c;来认识、理解、刻画客观世界和设计、构建相应的软件系统。 1.2 UML统一建模语言 为什么要使用UML UML基本概念 统一建模语言&#xff08;UML&#xff09;是一个支持模型化和软…

【电子通识】半导体工艺——刻蚀工艺

在文章【电子通识】半导体工艺——光刻工艺中我们讲到人们经常将 Photo Lithography&#xff08;光刻&#xff09;缩写成 Photo。光刻工艺是在晶圆上利用光线来照射带有电路图形的光罩&#xff0c;从而绘制电路。光刻工艺类似于洗印黑白照片&#xff0c;将在胶片上形成的图像印…

opencv之图像梯度

图像梯度 图像梯度计算的是图像变化的速度。对于图像的边缘部分&#xff0c;其灰度值变化较大&#xff0c;梯度值也较大&#xff1b;相反&#xff0c;对于图像中比较平滑的部分&#xff0c;其灰度值变化较小&#xff0c;相应的梯度值也较小。一般情况下&#xff0c;图像梯度计…

首批通过!华为云CodeArts Snap智能开发助手通过可信AI智能编码工具评估,获当前最高等级

近日&#xff0c;华为云CodeArts Snap智能开发助手在中国信通院组织的智能编码工具首轮评估中&#xff0c;最终获得4级评级, 成为国内首批通过该项评估并获得当前最高评级的企业之一。 此次评估以《智能化软件工程技术和应用要求 第2部分&#xff1a;智能开发能力》为依据&…

ubuntu 20.04 一直卡在登录界面,即使密码正确也无法登录(失败记录)

ubuntu 20.04 一直卡在登录界面&#xff0c;即使密码正确也无法登录 这次是装实体机&#xff0c;一次失败的尝试。。。 名称型号CPUIntel Xeon E5-2673 V3GPURTX 3060 mobile 安装的时候不要选install third-party software for graphics and Wi-fi hardware and additional …

Leetcode面试经典150题-55.跳跃游戏

解法都在代码里&#xff0c;不懂就留言或者私信 class Solution {public boolean canJump(int[] nums) {/**如果就一个位置&#xff0c;你本来就在这&#xff0c;肯定可以跳到*/if(nums.length 1) {return true;}/**这个题的解题思路是遍历数组&#xff0c;如果当前位置不在之…

每日OJ_牛客_数组中出现次数超过一半的数字

目录 牛客_数组中出现次数超过一半的数字 解析代码1 解析代码2 牛客_数组中出现次数超过一半的数字 数组中出现次数超过一半的数字__牛客网 给一个长度为 n 的数组&#xff0c;数组中有一个数字出现的次数超过数组长度的一半&#xff0c;请找出这个数字。例如输入一个长度为…

RP2040 C SDK clocks时钟源配置使用

RP2040 C SDK clocks时钟源配置使用 &#x1f33f;RP2040时钟源API函数文档&#xff1a;https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#group_hardware_clocks &#x1f341;RP2040时钟树&#xff1a; 系统时钟源可以来自外部时钟输入&#xff08;exte…

程序员如何写笔记并整理资料?

整理笔记 word。没错&#xff0c;我也看了网上一大堆软件&#xff0c;还有git管理等等。个人认为如果笔记只是记录个人的经验积累&#xff0c;一个word就够了&#xff0c;那些notepad&#xff0c;laTex个人觉得不够简练。word。 1.word可以插入任何文件附件(目前最大的word 20…