简体   繁体   English

活动转换 API 不工作

[英]Activity Transition API not working

I wish to use the new Activity transition API and after following the tutorial here I am not able to get the desired result.我希望使用新的 Activity transition API,按照此处的教程操作后,我无法获得所需的结果。

This is the code I have for setting the activity transition I wish to detect:这是我用于设置我希望检测的活动转换的代码:

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());

    }

}

And then requesting the activity transition updates:然后请求活动转换更新:

 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");
            }
        });

And this is the broadcastreceiver:这是 broadcastreceiver:

    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);
        }
    }
}

(The name has service in it cause initially I had kept it service but still not working.) (该名称中包含服务,因为最初我保留了它的服务但仍然无法使用。)

and in manifest:并在清单中:

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

You are using PendingIntent.getService() in combination with a BroadcastReceiver .您正在将PendingIntent.getService()BroadcastReceiver结合使用。

To receive pending intents with a BroadcastReceiver you have to retrieve the PendingIntent instance using PendingIntent.getBroadcast() .要使用BroadcastReceiver接收挂起的意图,您必须使用PendingIntent.getBroadcast()检索PendingIntent实例。 The corresponding developer guide concerning intents and intent filters can be found here .可以在此处找到有关意图和意图过滤器的相应开发人员指南。

Since Android 8 there are several background service limitations .由于 Android 8 有几个后台服务限制 Using an IntentService only works when the app is in foreground.使用IntentService仅在应用程序处于前台时才有效。 To receive activity transition updates after the app was closed you even have to use a BroadcastReceiver .要在应用程序关闭后接收活动转换更新,您甚至必须使用BroadcastReceiver For this purpose the BroadcastReceiver has to be registered in the application manifest with the corresponding permission, as Jan Maděra already mentioned.为此,必须在应用清单中注册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>

Furthermore onReceive() should only respond to your specific action, since intent filters are not guaranteed to be exclusive .此外onReceive()应该只响应您的特定操作,因为Intent 过滤器不能保证是 Exclusive

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 ...
            }
        }
    }
}

Requesting activity transition updates using PendingIntent.getBroadcast() :使用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);

Be aware that activity transition updates can be received delayed.请注意,活动转换更新可能会延迟接收。 This depends on the device and can also be affected by power management restrictions.这取决于设备,也可能受电源管理限制的影响。

This is an old post, but this answer might help someone.这是一个旧帖子,但这个答案可能对某人有所帮助。

Keep in mind that latency might actually be the problem, as it was in my case.请记住,延迟实际上可能是问题所在,就像我的情况一样。 I thought my implementation wasn't working, but in reality it was.我以为我的实现不起作用,但实际上确实如此。 The Activity Transitions API just has a huge delay of about 1 minute to notify you of transitions. Activity Transitions API 只是有大约 1 分钟的巨大延迟来通知您转换。 So try walking around or driving for a few minutes to start receiving notifications.因此,请尝试四处走动或开车几分钟以开始接收通知。

I faced similar issue but helped me add receiver to the manifest我遇到了类似的问题,但帮助我将接收器添加到清单中

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

I also tried the aforementioned Codelab tutorial, as well as a few other examples, but none of them worked;我还尝试了前面提到的 Codelab 教程以及其他一些示例,但都没有奏效; BroadcastReceiver.onReceive() was never called, no matter how I set it up. BroadcastReceiver.onReceive()从未被调用,无论我如何设置。

What did work was to use requestActivityUpdates() instead of requestActivityTransitionUpdates() .有效的是使用requestActivityUpdates()而不是requestActivityTransitionUpdates() According to the document , requestActivityTransitionUpdates() is a better choice, because it improves accuracy and consumes less power, but it's not better choice for me if it doesn't do what it's supposed to do.根据文档requestActivityTransitionUpdates()是更好的选择,因为它提高了准确性并消耗了更少的电量,但如果它没有做它应该做的事情,它对我来说并不是更好的选择。 Here is the summary on what I did.这是我所做的总结。

[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.
    }
}

At some point it seems that the following intent for an explicit class stopped working (or maybe never worked?):在某些时候,以下针对显式 class 的意图似乎停止了工作(或者可能从未工作过?):

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

Instead, I created the intent by passing in the action in the intent constructor, as follows:相反,我通过在意图构造函数中传递操作来创建意图,如下所示:

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

...and then I started to get callbacks successfully from the Activity Transition API. ...然后我开始从 Activity Transition API 成功获得回调。

Note that this approach is used in the latest codelab as well: https://github.com/googlecodelabs/activity_transitionapi-codelab/blob/master/complete/src/main/java/com/google/example/android/basicactivityrecognitiontransitionsample/MainActivity.java#L134请注意,最新的代码实验室也使用了这种方法: https://github.com/googlecodelabs/activity_transitionapi-codelab/blob/master/complete/src/main/java/com/google/example/android/basicactivityrecognitiontransitionsample/MainActivity .java#L134

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM