活动识别API

14

最近的 Google Play 服务更新中,有人在使用活动识别 API 时遇到问题吗?

我在应用程序中实现了它。在 5.0 更新之前,它工作得非常完美。但现在,即使用户在走路或静止不动时,它也会返回 IN_VEHICLE。:/

而且根本不返回WALKINGRUNNINGON_FOOT

活动识别 API 是否有任何更改我需要知道的?

如果您需要更多详细信息,请告诉我。


1
ActivityRecognitionApi已经被弃用,Google建议使用无连接API ActivityRecognitionClient - g2server
4个回答

13
“WALKING”和“RUNNING”活动以在列表中作为次要活动(ActivityRecognitionResult.getProbableActivities()的形式出现,您需要解析它们。”
// Get the update
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);

// Get the most probable activity from the list of activities in the update
DetectedActivity mostProbableActivity = result.getMostProbableActivity();

// Get the type of activity
int activityType = mostProbableActivity.getType();

if (activityType == DetectedActivity.ON_FOOT) {
    DetectedActivity betterActivity = walkingOrRunning(result.getProbableActivities());
    if (null != betterActivity)
        mostProbableActivity = betterActivity;
}

private DetectedActivity walkingOrRunning(List<DetectedActivity> probableActivities) {
    DetectedActivity myActivity = null;
    int confidence = 0;
    for (DetectedActivity activity : probableActivities) {
        if (activity.getType() != DetectedActivity.RUNNING && activity.getType() != DetectedActivity.WALKING)
            continue;

        if (activity.getConfidence() > confidence)
            myActivity = activity;
    }

    return myActivity;
}

我今晚测试了上面的代码,无论是步行还是跑步,它似乎都表现得相当不错。如果您没有明确地筛选只有 RUNNINGWALKING,您可能会得到错误的结果。
下面是处理新活动结果的完整方法。我直接从示例应用程序中提取了这个方法,并已经测试了几天,结果良好。
/**
 * Called when a new activity detection update is available.
 */
@Override
protected void onHandleIntent(Intent intent) {
    Log.d(TAG, "onHandleIntent");

    // Get a handle to the repository
    mPrefs = getApplicationContext().getSharedPreferences(
            Constants.SHARED_PREFERENCES, Context.MODE_PRIVATE);

    // Get a date formatter, and catch errors in the returned timestamp
    try {
        mDateFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance();
    } catch (Exception e) {
        Log.e(TAG, getString(R.string.date_format_error));
    }

    // Format the timestamp according to the pattern, then localize the pattern
    mDateFormat.applyPattern(DATE_FORMAT_PATTERN);
    mDateFormat.applyLocalizedPattern(mDateFormat.toLocalizedPattern());

    // If the intent contains an update
    if (ActivityRecognitionResult.hasResult(intent)) {

        // Get the update
        ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);

        // Log the update
        logActivityRecognitionResult(result);

        // Get the most probable activity from the list of activities in the update
        DetectedActivity mostProbableActivity = result.getMostProbableActivity();

        // Get the confidence percentage for the most probable activity
        int confidence = mostProbableActivity.getConfidence();

        // Get the type of activity
        int activityType = mostProbableActivity.getType();
        mostProbableActivity.getVersionCode();

        Log.d(TAG, "acitivty: " + getNameFromType(activityType));

        if (confidence >= 50) {
            String mode = getNameFromType(activityType);

            if (activityType == DetectedActivity.ON_FOOT) {
                DetectedActivity betterActivity = walkingOrRunning(result.getProbableActivities());

                if (null != betterActivity)
                    mode = getNameFromType(betterActivity.getType());
            }

            sendNotification(mode);
        }
    }
}

private DetectedActivity walkingOrRunning(List<DetectedActivity> probableActivities) {
    DetectedActivity myActivity = null;
    int confidence = 0;
    for (DetectedActivity activity : probableActivities) {
        if (activity.getType() != DetectedActivity.RUNNING && activity.getType() != DetectedActivity.WALKING)
            continue;

        if (activity.getConfidence() > confidence)
            myActivity = activity;
    }

    return myActivity;
}

/**
 * Map detected activity types to strings
 *
 * @param activityType The detected activity type
 * @return A user-readable name for the type
 */
private String getNameFromType(int activityType) {
    switch (activityType) {
        case DetectedActivity.IN_VEHICLE:
            return "in_vehicle";
        case DetectedActivity.ON_BICYCLE:
            return RIDE;
        case DetectedActivity.RUNNING:
            return RUN;
        case DetectedActivity.WALKING:
            return "walking";
        case DetectedActivity.ON_FOOT:
            return "on_foot";
        case DetectedActivity.STILL:
            return "still";
        case DetectedActivity.TILTING:
            return "tilting";
        default:
            return "unknown";
    }
}

谢谢回复。我不需要知道用户是在走路还是跑步,我只需要知道用户在步行。所以我就这样了。现在我需要做的就是弄清楚为什么API在用户步行或坐着时返回IN_VEHICLE。 - DrkStr
你是否基于置信度进行过滤,并使用最可能的活动?DetectedActivity mostProbableActivity = result.getMostProbableActivity();mostProbableActivity.getConfidence() >= 50 - ejf
不,我只是在使用getMostProbableActivity()。今天我会尝试使用getConfidence(),然后告诉你它的效果如何。 - DrkStr

1
主要变化是ON_FOOT现在返回一个检测到的活动列表。现在请使用getMostProbableActivities()。 当ON_FOOT时,此解决方案获取步行或奔跑,获取检测到的活动列表如下:
//Get the list from the result
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
ArrayList<DetectedActivity> activityList = new ArrayList<DetectedActivity>(result.getProbableActivities());

//Get the most probable activity
getMostProbableActivity(activityList);

现在,将您的列表传递给以下代码以查找最可能的活动:
private DetectedActivity getMostProbableActivity(List<DetectedActivity> detectedActivityList)
{
DetectedActivity result = null;

//Find the most probably activity in the list
for(DetectedActivity detectedActivity : detectedActivityList)
{
    if(detectedActivity.getType() != DetectedActivity.ON_FOOT)
    {
        if(result == null)
        {
            result = detectedActivity;
        }
        else
        {
            if(result.getConfidence() < detectedActivity.getConfidence())
            {
                result = detectedActivity;
            }
        }
    }
}

return result;

}


1
你可以尝试使用这个简单的“for循环”来确保你的用户正在驾驶。
for (DetectedActivity detectedActivity : detectedActivityList)
        {
           {
              if(DetectedActivity == “In_Vehicle” && result.getConfidence()> 75)
                     {
                        // output = User is Driving;
                        // Perform task 
                     }
           }
        }

请记住,为了让Google Play服务确信您的用户正在执行某项任务,置信度必须大于75,只有这样才能确定任务已完成。 或者,您可以尝试一些免费的SDK,如Tranql、Neura或ContextHub,这些SDK可以为您提供有关用户活动和位置的更好洞察。


0

我有Google Play服务5.0.84,它在我的Nexus 5上运行良好。我不知道你在说什么,所以这可能是你代码中的错误。

我的应用程序每分钟不断采样,并返回(大多数情况下)正确的活动。驾驶/步行/倾斜/步行...所有的东西都来了。

此外,如果您没有使用getMostProbableActivity,那么您应该使用它!评论:确实可能会在特定设备或某些供应商固件中出现问题,但这不太可能。


我正在使用getMostProbableActivity()。我还没有尝试过getConfidence。 - DrkStr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接