活动过渡API无法正常工作

时间:2018-08-15 12:52:53

标签: android android-pendingintent android-broadcastreceiver activity-recognition activitytransitionapi

我希望使用新的Activity过渡API,并且在遵循了here教程之后,我无法获得所需的结果。

这是我用于设置要检测的活动过渡的代码:

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>

4 个答案:

答案 0 :(得分:3)

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

要接收带有BroadcastReceiver的待定意图,您必须使用PendingIntent来检索PendingIntent.getBroadcast()实例。可以在here中找到有关意图和意图过滤器的相应开发人员指南。

自Android 8起,有多个background service limitations。仅当应用程序处于前台时,才使用IntentService。要在应用关闭后接收活动转换更新,您甚至必须使用BroadcastReceiver。为此,{JanMaděra已经提到过,BroadcastReceiver必须在应用清单中获得相应的许可。

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

此外,自intent filters are not guaranteed to be exclusive起,onReceive()应该只响应您的特定操作。

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

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

答案 1 :(得分:2)

我遇到了类似的问题,但是帮助我在清单中添加了收件人

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

答案 2 :(得分:1)

我还尝试了前面提到的Codelab教程以及其他一些示例,但是没有一个起作用。无论如何设置,BroadcastReceiver.onReceive()从未被调用过。

起作用的是使用requestActivityUpdates()而不是requestActivityTransitionUpdates()。根据{{​​3}}的说法,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.
    }
}

答案 3 :(得分:0)

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

请记住,就我而言,延迟实际上可能是问题所在。我以为我的实现没有用,但实际上是可行的。 Activity Transitions API仅有大约1分钟的巨大延迟,以通知您进行转换。因此,尝试四处走动或开车几分钟以开始接收通知。