活动转换 API 不起作用



我希望使用新的活动转换 API,按照此处的教程进行操作后,我无法获得所需的结果。

这是我用于设置我希望检测的活动转换的代码:

public void setActivityTransitions() {
transitionList = new ArrayList<>();
ArrayList<Integer> activities = new ArrayList<>(Arrays.asList(
DetectedActivity.STILL,
DetectedActivity.WALKING,
DetectedActivity.ON_FOOT,
DetectedActivity.RUNNING,
DetectedActivity.ON_BICYCLE,
DetectedActivity.IN_VEHICLE));
for (int activity :
activities) {
transitionList.add(new ActivityTransition.Builder()
.setActivityType(activity)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER).build());
transitionList.add(new ActivityTransition.Builder()
.setActivityType(activity)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT).build());
}
}

然后请求活动转换更新:

ActivityTransitionRequest activityTransitionRequest = new ActivityTransitionRequest(transitionList);
Intent intent = new Intent(context, ActivityDetectorTransitionService.class);
intent.setAction("com.test.activityrecognition.START_ACTIVITY_TRANSITION_DETECTION_ALARM");
PendingIntent pendingIntent = PendingIntent.getService(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Task<Void> task = ActivityRecognition.getClient(context).requestActivityTransitionUpdates(activityTransitionRequest, pendingIntent);
task.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void result) {
System.out.println("onSuccess");
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
e.printStackTrace();
System.out.println("onFailure");
}
});

这是广播接收器:

public class ActivityDetectorTransitionService extends BroadcastReceiver {
private static final String TAG = "ActivityDetectorTransitionService";
@Override
public void onReceive(Context context, Intent intent) {
if (ActivityTransitionResult.hasResult(intent)) {
ActivityTransitionResult activityTransitionResult = ActivityTransitionResult.extractResult(intent);
ActivityDetectorTransitionAPI.getInstance().handleActivityRecognitionResult(activityTransitionResult);
}
}
}

(这个名字有服务,因为最初我一直保持服务,但仍然不起作用。

并在清单中:

<receiver
android:name=".tracking.activityrecognition.ActivityDetectorTransitionService">
<intent-filter>
<action android:name="com.test.activityrecognition.START_ACTIVITY_TRANSITION_DETECTION_ALARM"/>
</intent-filter>
</receiver>

您正在将PendingIntent.getService()BroadcastReceiver结合使用。

要接收带有BroadcastReceiver的挂起意图,您必须使用PendingIntent.getBroadcast()检索PendingIntent实例。可在此处找到有关意图和意图过滤器的相应开发者指南。

自 Android 8 起,有几个后台服务限制。仅当应用位于前台时,才可以使用IntentService。要在应用程序关闭后接收活动转换更新,您甚至必须使用BroadcastReceiver.为此,BroadcastReceiver必须具有相应的权限在应用程序清单中注册,正如 Jan Maděra 已经提到的。

<receiver android:name="com.mypackage.ActivityTransitionBroadcastReceiver"
android:exported="false"
android:permission="com.google.android.gms.permission.ACTIVITY_RECOGNITION">
<intent-filter>
<action android:name="com.mypackage.ACTION_PROCESS_ACTIVITY_TRANSITIONS" />
</intent-filter>
</receiver>

此外,onReceive()应仅响应您的特定操作,因为不保证 Intent 过滤器是排他性的。

public class ActivityTransitionBroadcastReceiver extends BroadcastReceiver {
public static final String INTENT_ACTION = "com.mypackage" +
".ACTION_PROCESS_ACTIVITY_TRANSITIONS";
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && INTENT_ACTION.equals(intent.getAction())) {
if (ActivityTransitionResult.hasResult(intent)) {
ActivityTransitionResult intentResult = ActivityTransitionResult
.extractResult(intent);
// handle activity transition result ...
}
}
}
}

使用PendingIntent.getBroadcast()请求活动转换更新:

ActivityTransitionRequest request = new ActivityTransitionRequest(transitionList);
Intent intent = new Intent(context, ActivityTransitionBroadcastReceiver.class);
intent.setAction(ActivityTransitionBroadcastReceiver.INTENT_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Task<Void> task = ActivityRecognition.getClient(context)
.requestActivityTransitionUpdates(request, pendingIntent);

请注意,活动转换更新可能会延迟接收。这取决于设备,也可能受到电源管理限制的影响。

这是一个古老的帖子,但这个答案可能会对某人有所帮助。

请记住,延迟实际上可能是问题所在,就像我的情况一样。我以为我的实现不起作用,但实际上确实如此。活动转换 API 只有大约 1 分钟的巨大延迟来通知您转换。因此,请尝试四处走动或开车几分钟以开始接收通知。

我遇到了类似的问题,但帮助我将接收器添加到清单中

<receiver
android:name=".service.ActivityTransitionReceiver"
android:permission="com.google.android.gms.permission.ACTIVITY_RECOGNITION"
android:exported="false" />

我还尝试了前面提到的 Codelab 教程以及其他一些示例,但没有一个有效;BroadcastReceiver.onReceive()从来没有被召唤过,无论我如何设置它。

起作用的是使用requestActivityUpdates()而不是requestActivityTransitionUpdates()。根据该文件,requestActivityTransitionUpdates()是一个更好的选择,因为它提高了准确性并消耗了更少的功率,但如果它不做它应该做的事情,它对我来说不是更好的选择。以下是我所做的事情的摘要。

[AndroidManifest.xml]
<receiver
android:name=".TransitionUpdatesBroadcastReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="TRANSITION_UPDATES" />
</intent-filter>
</receiver>
// This is in your Activity/Fragment.
private val pendingIntent: PendingIntent by lazy {
val intent = Intent(context, TransitionUpdatesBroadcastReceiver::class.java)
intent.action = TRANSITION_UPDATES
PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ActivityRecognition.getClient(context)
.requestActivityUpdates(1_000, pendingIntent)    <-- Here.
}
override fun onDestroy() {
super.onDestroy()
ActivityRecognition.getClient(context)
.removeActivityUpdates(pendingIntent)
}
class TransitionUpdatesBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// Do what you need to do with intent.
}
}

在某些时候,显式类的以下意图似乎停止工作(或者可能从未起作用?

Intent intent = new Intent(context, ActivityDetectorTransitionService.class);

相反,我通过在 intent 构造函数中传递操作来创建 tent,如下所示:

Intent intent = new Intent("com.test.activityrecognition.START_ACTIVITY_TRANSITION_DETECTION_ALARM");

。然后我开始从活动转换 API 成功获取回调。

请注意,此方法也用于最新的 Codelab: https://github.com/googlecodelabs/activity_transitionapi-codelab/blob/master/complete/src/main/java/com/google/example/android/basicactivityrecognitiontransitionsample/MainActivity.java#L134

最新更新