Android 13/14下ActivityRecognitionClient请求活动更新成功但BroadcastReceiver无响应的问题
我之前也碰到过几乎一模一样的问题,在Android 13/14上调用requestActivityUpdates返回成功,但接收器就是收不到回调,折腾了好一阵才找到几个关键的坑,你可以逐一排查看看:
1. 先确认Receiver是否真的没被触发
你现在的日志里完全没有Receiver的输出,首先要排除是Receiver代码的问题(比如日志TAG写错、逻辑判断跳过了日志)。建议先在onReceive最开头加一行最基础的日志:
class ActivityRecognitionReceiver : BroadcastReceiver() { private val TAG = "ATS-ActivityRecognitionReceiver" override fun onReceive(context: Context, intent: Intent) { // 先加这行,确认Receiver是否收到了任何Intent Log.d(TAG, "🔔 Receiver received an intent! Action: ${intent.action}") if (ActivityRecognitionResult.hasResult(intent)) { val result = ActivityRecognitionResult.extractResult(intent) // ... 原有逻辑 } else { Log.w(TAG, "No ActivityRecognitionResult in intent") } } }
如果加了之后还是没有这个TAG的日志,说明Intent根本没到Receiver,那问题出在PendingIntent或者组件注册上;如果有日志但提示没有Result,再排查ActivityRecognition的配置。
2. 清理旧的PendingIntent再创建新的
Android系统会缓存PendingIntent,如果你之前用相同requestCode创建过PendingIntent(比如APP重启过),新的PendingIntent可能不会生效。建议在创建新PendingIntent前先取消旧的:
override fun onCreate() { super.onCreate() mActivityRecognitionClient = ActivityRecognition.getClient(this) // 先取消旧的PendingIntent(如果存在) val oldIntent = Intent(this, ActivityRecognitionReceiver::class.java) val oldPendingIntent = PendingIntent.getBroadcast( this, 1, // 和你之前用的requestCode一致 oldIntent, PendingIntent.FLAG_NO_CREATE or PendingIntent.FLAG_MUTABLE ) oldPendingIntent?.cancel() // 再创建新的PendingIntent val intent = Intent(this, ActivityRecognitionReceiver::class.java) mPendingIntent = PendingIntent.getBroadcast( this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE ) requestActivityUpdates() }
3. 确认Manifest中Receiver的类名完全正确
如果Manifest里的Receiver类名写错(比如包名不全、类名拼写错误),系统找不到Receiver,自然不会发送Intent。比如你的ActivityRecognitionReceiver如果在子包com.yourapp.receivers下,Manifest里需要写全路径:
<receiver android:name="com.yourapp.receivers.ActivityRecognitionReceiver" android:exported="true" />
如果是和Application同包,写.ActivityRecognitionReceiver是对的,但建议直接写全类名避免歧义。
4. 测试时做更持续、明显的动作
Activity Recognition的系统算法会根据设备状态调整更新频率:如果设备静止不动,系统可能会大幅降低更新频率甚至停止发送,直到检测到明显的动作变化。你现在设置的是3秒间隔,但实际系统可能不会严格按照这个时间发送。建议测试时:
- 拿着设备持续走路/跑步5分钟以上
- 或者切换不同的动作(比如从走路到坐下,再到站起来走路)
- 避免只是小幅度晃动设备
5. 检查Foreground Service是否持续运行
虽然你的日志显示前台服务启动成功,但Android 13/14对前台服务的管控更严格,可能服务在请求更新后被系统回收。你可以:
- 打开设备的「开发者选项」→「正在运行的服务」,确认你的
BackgroundDetectedActivitiesService是否一直在运行 - 给服务的
onDestroy方法加日志,看看是否被销毁:
override fun onDestroy() { super.onDestroy() Log.d(TAG, "⚠️ Foreground service destroyed!") }
如果服务被销毁,Activity Recognition的更新也会被系统取消,自然收不到回调。这种情况需要优化服务的存活策略,比如避免内存泄漏、处理系统的内存回收信号。
6. 额外权限排查(非必须,但可以试试)
虽然官方文档说Activity Recognition只需要ACTIVITY_RECOGNITION权限,但部分Android 13/14的定制ROM可能要求同时拥有ACCESS_FINE_LOCATION权限才能接收更新。你可以尝试:
- 在Manifest中添加权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- 在运行时请求该权限,然后再测试。
7. 确认PendingIntent的FLAG组合
你已经用了FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE,这在Android 12+是正确的(必须指定MUTABLE/IMMUTABLE,而UPDATE_CURRENT允许更新Intent的内容)。但如果还是有问题,可以尝试换成FLAG_IMMUTABLE(因为你这里的Intent不需要后续更新内容):
mPendingIntent = PendingIntent.getBroadcast( this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE )
按照这个顺序排查,应该能找到问题所在。我当时是因为旧的PendingIntent没有被取消,导致新的请求绑定到了失效的Receiver,清理旧PendingIntent后就正常收到回调了!




