使用广播接收器无法检测用户活动切换,求助Activity Transition API方案
Hey there! Let's break down why your Activity Transition API setup isn't picking up in-vehicle state changes. From the code snippet you shared, there are several common fixes and checks we can walk through:
1. Complete Your Transition Request Setup
Your code looks truncated—first, make sure you're defining both enter and exit transitions for the IN_VEHICLE state, and properly submitting the request to the Activity Recognition client:
// Build full transition list val transitions = mutableListOf<ActivityTransition>() // Detect when user enters a vehicle transitions.add(ActivityTransition.Builder() .setActivityType(DetectedActivity.IN_VEHICLE) .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER) .build()) // Detect when user exits a vehicle transitions.add(ActivityTransition.Builder() .setActivityType(DetectedActivity.IN_VEHICLE) .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT) .build()) // Create request and submit it val transitionRequest = ActivityTransitionRequest(transitions) val activityRecognitionClient = ActivityRecognition.getClient(context) activityRecognitionClient.requestActivityTransitionUpdates(transitionRequest, pendingIntent) .addOnSuccessListener { // Confirm the request was accepted Log.d("TransitionAPI", "Successfully registered for updates") } .addOnFailureListener { e -> // Debug failure causes (e.g., missing permissions) Log.e("TransitionAPI", "Failed to register updates", e) }
2. Verify Permissions Are Granted
The Activity Transition API requires explicit permissions, especially on Android 10+:
- Add this to your
AndroidManifest.xml:<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" /> - Request runtime permission before initializing the API:
private const val PERMISSION_REQUEST_CODE = 1001 if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACTIVITY_RECOGNITION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( yourActivity, arrayOf(Manifest.permission.ACTIVITY_RECOGNITION), PERMISSION_REQUEST_CODE ) }
3. Ensure Your Broadcast Receiver Is Properly Registered
Your ActivityTransitionReceiver won't receive events if it's not registered correctly:
Option 1: Static Registration (Manifest)
<receiver android:name=".ActivityTransitionReceiver" android:exported="false"> <intent-filter> <!-- Use a unique action string for your app --> <action android:name="com.your.app.package.ACTIVITY_TRANSITION_EVENT" /> </intent-filter> </receiver>
Make sure your Intent uses this action when creating the PendingIntent:
val intent = Intent("com.your.app.package.ACTIVITY_TRANSITION_EVENT") intent.setClass(context, ActivityTransitionReceiver::class.java)
Option 2: Dynamic Registration (In Activity/Fragment)
val receiver = ActivityTransitionReceiver() val filter = IntentFilter("com.your.app.package.ACTIVITY_TRANSITION_EVENT") context.registerReceiver(receiver, filter)
Don't forget to unregister it in onDestroy() to avoid leaks.
4. Fix PendingIntent Flags for Android 12+
On Android 12 and above, you must specify either FLAG_IMMUTABLE or FLAG_MUTABLE for PendingIntents:
val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE } else { PendingIntent.FLAG_UPDATE_CURRENT } val pendingIntent = PendingIntent.getBroadcast( context, requestCode, intent, pendingIntentFlags )
5. Validate Your Receiver Implementation
Double-check that your receiver is properly extracting and handling transition events:
class ActivityTransitionReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if (ActivityTransitionResult.hasResult(intent)) { val result = ActivityTransitionResult.extractResult(intent) result?.transitionEvents?.forEach { event -> when (event.activityType) { DetectedActivity.IN_VEHICLE -> { when (event.transitionType) { ActivityTransition.ACTIVITY_TRANSITION_ENTER -> Log.d("Transition", "User entered vehicle") ActivityTransition.ACTIVITY_TRANSITION_EXIT -> Log.d("Transition", "User exited vehicle") } } } } } } }
6. Test on a Real Device
Emulators can't reliably simulate vehicle movement or sensor data. Test your code on a physical device while actually entering/exiting a car—state changes require consistent sensor input to trigger.
内容的提问来源于stack exchange,提问作者Mehul Kanzariya

