Android15 无法接收到应用自身发出的广播分析解决
Android15 无法接收到应用自身发出的广播分析解决
文章目录
- Android15 无法接收到应用自身发出的广播分析解决
- 一、前言
- 二、无法接收到应用内自身发送的普通广播分析和解决
- 1、一段简单的应用广播监听和发送代码
- 2、Android 15 无法接收到应用内普通广播的分析
- Android 广播核心流程链
- 3、无法接收到应用内自身发送的普通广播解决
- 三、其他
- 1、Android15 无法接收到应用内自身发出的广播分析解决小结
- 2、自身发送的普通广播的其他验证
- 3、Android 中的 本地广播LocalBroadcastManager
- 4、Android14 普通应用registerReceiver注册广播报错One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be
一、前言
最近Android15新建的项目发现一个问题:应用内的广播发送后,无法接收到了。
defaultConfig {applicationId "com.liwenzhi.broadcasttest"minSdk 31targetSdk 35versionCode 1versionName "1.0"}
把上面 的 targetSdk 替换成33 就可以正常替换了。
难道Android13 版本之后,系统对自身发出的普通广播做了限制接收?
本文简单分析解决看看。
二、无法接收到应用内自身发送的普通广播分析和解决
1、一段简单的应用广播监听和发送代码
package com.liwenzhi.broadcasttest;import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);LogUtil.debug("");registerBroadcast(this);//动态监听广播}@Overrideprotected void onDestroy() {super.onDestroy();unRegisterBroadcast(this);}//发送自定义广播public void sendBroadcast(View view) {LogUtil.debug("");Intent intent = new Intent("TestBroadcast");sendBroadcast(intent);}//注册广播监听public void registerBroadcast(Context context) {LogUtil.debug("");IntentFilter filter = new IntentFilter();filter.addAction("TestBroadcast"); //自定义广播filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); //网络监听广播registerReceiver(mReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED);}public void unRegisterBroadcast(Context context) {context.unregisterReceiver(mReceiver);}//广播接收者+打印private final BroadcastReceiver mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {final String action = intent.getAction();LogUtil.debug("onReceive: action = " + action);switch (action) {case ACTION_NET_CHANGE_ACTION:LogUtil.debug("网络变化");break;case "TestBroadcast":LogUtil.debug("自定义广播接收");break;}}};}
之前Android13 经常这样使用是OK的,但是到Android15 就不行了;
上面广播监听是正常的,开关wifi能接收到网络变化的广播;
所以为啥Android15 ,无法接收到应用内发送的普通广播了?
为啥会这样暂时未分析出具体原因和具体哪行代码导致。
但是大概过程是了解一些的:
2、Android 15 无法接收到应用内普通广播的分析
Android 广播核心流程链
应用发送广播 → ContextImpl → Binder 调用 →
AMS(匹配接收者、调度) //重点:ActivityManagerService
→ Binder 调用 → 目标进程ActivityThread → 调用BroadcastReceiver.onReceive()
ActivityManagerService 里面有收集所有广播的集合:
AMS 维护 mRegisteredReceivers 映射表,存储已注册的动态接收器:
final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
中间有非常复杂的过程判断逻辑,会对广播列表进行排序,分发前做各种判断处理;
用AI 搜到的说是 isSameComponentApplicationLocked 方法会判断应用内发送的广播,但是源码未找到这个方法。
所以这里暂时只能停供一个思路,研究看看 ActivityManagerService 应用内广播分发的具体流程。
ActivityManagerService 是有点多的,大概两万多行,看着头疼。
虽然目前未分析出导致应用内无法接收到自身发出的普通广播的具体的代码,但是也是有解决方案的:
3、无法接收到应用内自身发送的普通广播解决
发送本地广播就可以解决这个问题:
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
需要注意的是,必须要注册本地广播,普通广播接收者是无法接收本地广播的信息的:
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.BRO_TEST"); //自定义广播
filter.addAction(Intent.ACTION_TIME_CHANGED);//time_set
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); //网络监听广播
//registerReceiver(mReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED);//普通关闭注册
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter); //自定义广播注册
上面可以看到本地广播注册和普通动态广播注册是类型的,只是具体注册调用的api不同。
三、其他
1、Android15 无法接收到应用内自身发出的广播分析解决小结
Android 15 无法接收到应用内自身发出的普通广播的分析主要逻辑在 ActivityManagerService
目前还未找到导致问题的具体代码,有兴趣的可以自行研究看看。
解决方法:
使用 LocalBroadcastManager 发送和监听本地广播
这个估计也不算问题,估计是Google 官方对于Android15 的优化处理,可能是为了效率或者安全。
本地广播LocalBroadcastManager并非Android15才有,早在Android5 已经存在了。
2、自身发送的普通广播的其他验证
下面是一些其他验证情况:
(1)验证试了Android14 也是上面问题,Android13 没有这个问题,所以Android14或者更新的系统会有这个问题
(2)Android14或者更新的版本上,发送普通广播,其他应用是可以动态监听到的;
(3)Android 13 AML方案,使用SKD 35编译的应用也是可以接收到自身发出的普通广播;
理论上Android15版本的应用,不能安装到Android13 版本上,这里可能是系统就行了适配,实际还是Android13 的应用。
3、Android 中的 本地广播LocalBroadcastManager
本地广播(注册),数据安全,其他app也不能给你发广播(接收)。也比系统广播高效。
一般使用在应用内部不同fragment和Activity的交互,或者界面和service 的交互。
BroadcastReceiver设计的初衷是从全局考虑可以方便应用程序和系统、应用程序之间、应用程序内的通信,
所以对单个应用程序而言BroadcastReceiver是存在安全性问题的(恶意程序脚本不断的去发送你所接收的广播)。
为了解决这个问题LocalBroadcastManager就应运而生了。
https://blog.csdn.net/wenzhi20102321/article/details/134042436
4、Android14 普通应用registerReceiver注册广播报错One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be
Android14 普通应用注册广播registerReceiver会报错,提示需要添加一个参数RECEIVER_EXPORTED 或者 RECEIVER_NOT_EXPORTED;系统framework或者系统应用是不会报这个错误的!
这个问题比较好解决,加一个参数就行,但是网上目前没有人对这个问题今天深入分析。
本文对registerReceiver报错进行分析,具体到哪个类哪行代码报错。
https://blog.csdn.net/wenzhi20102321/article/details/138345708