You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android 13/14下ActivityRecognitionClient请求活动更新成功但BroadcastReceiver无响应的问题

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权限才能接收更新。你可以尝试:

  1. 在Manifest中添加权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. 在运行时请求该权限,然后再测试。

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后就正常收到回调了!

火山引擎 最新活动