MY_PACKAGE_REPLACED不生效:安卓如何监听应用升级事件
问题根因
- 监听
android.intent.action.PACKAGE_REPLACED广播时,未在intent-filter中声明packagescheme,系统会直接过滤掉未携带匹配data规则的广播接收器。 - Android 11(API 30)对静态广播的注册规则校验更严格,未匹配intent-filter所有规则的接收器无法收到对应广播。
最优解决步骤
1. 优先使用MY_PACKAGE_REPLACED监听自身升级
该广播是系统专门为监听自身应用升级设计的,不需要额外配置data规则,也不会收到其他应用的替换事件,性能更优。
修正后的Manifest静态注册配置:
<receiver android:name=".Receiver" android:enabled="true" android:exported="true" tools:ignore="HardcodedDebugMode"> <!-- 监听自身应用升级 --> <intent-filter> <action android:name="android.intent.action.MY_PACKAGE_REPLACED" /> </intent-filter> <!-- 监听开机启动 --> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
注意:android.intent.action.CONNECTIVITY_CHANGE广播从Android 7.0(API 24)开始就禁止静态注册接收,你需要在活跃的Service/Activity中动态注册该广播接收器,静态注册永远无法收到该事件。
2. 升级Receiver的逻辑判断
对应修改onReceive里的action判断即可:
@Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.d(TAG, "action = " + action); if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { Log.d(TAG, "BOOT COMPLETED, Ping start..."); } else if (Intent.ACTION_MY_PACKAGE_REPLACED.equals(action)) { Log.d(TAG, "PACKAGE REPLACED, upgrade ping..."); } else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { Log.d(TAG, "network status changed..."); } }
3. 测试注意事项
- 不要直接用Android Studio的Run按钮安装测试,该安装方式不会触发
MY_PACKAGE_REPLACED广播,请使用adb install -r 你的安装包.apk命令覆盖安装测试。 - 部分国产定制ROM会对后台广播做拦截,请将应用加入系统省电白名单、允许自启动后再测试。
如果你坚持要用PACKAGE_REPLACED监听,需要给对应的intent-filter添加data规则:
<intent-filter> <action android:name="android.intent.action.PACKAGE_REPLACED" /> <data android:scheme="package" /> </intent-filter>
收到广播后还要额外判断替换的包名是否是你自身应用的包名,避免处理其他应用的替换事件。
内容的提问来源于stack exchange,提问作者Happy
相关产品推荐
相关产品推荐

