问题
Using my Android device how can I detect if the user is walking, cycling or driving? I have checked the Google Fit app. It differentiates between running, cycling and driving. I am puzzled about what algorithms I should use to differentiate between these activities.
I know I would have to use the accelerometer sensor. But still I can't differentiate these activities.
回答1:
You can use the GooglePlayServices for this.
It Provides special apis for ActivityRecognition, which returns the User activity with confidence level for each.
https://developer.android.com/reference/com/google/android/gms/location/ActivityRecognitionClient.html
http://developer.android.com/training/location/activity-recognition.html
回答2:
This question is quite old, but since there are new technologies out there, i thought it was worth mentioning, if anyone is still encountering this issue.
I can come up with 3 options :
- You can implement your own technique for detecting walking, driving, cycling - using Activity recognition and receiving location updates, though i recommend not to do so, don't reinvent the wheel, there are good apis developed already, it's 2016 now.
You could use a free sdk of Neura which can send you an event when your user starts/finishes driving, start/finish walking, start/finish running, read more of the events you can get from Neura.
Check out this git project : Basically, the project has all the events that Nuera can detect. Its very easy to just take this project and make it your own.
I highly recommend using this Neura sdk option.
You could use google's FenceApi in order to declare fences. For example, this is a code for detecting a driving fence.
Though this approach seems good, i've faced with the fact that this api didn't tell me sometimes when the events happened, and sometimes it took a long time after i started walking/running when the api told me of that event.
a. include dependency to your app's build.gradle file :
compile 'com.google.android.gms:play-services-location:+' compile 'com.google.android.gms:play-services-contextmanager:+'
b. Manifest definitions :
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" > <meta-data android:name="com.google.android.awareness.API_KEY" android:value="PUT_YOUR_AWARENESS_KEY_HERE" /> <activity android:name=".MainActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
PUT_YOUR_AWARENESS_KEY_HERE : You need to generate a key here.
c. Your MainActivity class - explanations attached to the code :
public class MainActivity extends Activity { private GoogleApiClient mGoogleApiClient; private PendingIntent mPendingIntent; private FenceReceiver mFenceReceiver; // The intent action which will be fired when your fence is triggered. private final String FENCE_RECEIVER_ACTION = BuildConfig.APPLICATION_ID + "FENCE_RECEIVER_ACTION"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(Awareness.API).build(); mGoogleApiClient.connect(); // Set up the PendingIntent that will be fired when the fence is triggered. mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(FENCE_RECEIVER_ACTION), 0); // The broadcast receiver that will receive intents when a fence is triggered. mFenceReceiver = new FenceReceiver(); registerReceiver(mFenceReceiver, new IntentFilter(FENCE_RECEIVER_ACTION)); createFence(DetectedActivityFence.IN_VEHICLE, "InVehicleFence"); } @Override public void onDestroy() { try { unregisterReceiver(mFenceReceiver); //Don't forget to unregister the receiver } catch (Exception e) { e.printStackTrace(); } super.onDestroy(); } private void createFence(int detectedActivityFence, final String fenceKey) { AwarenessFence fence = DetectedActivityFence.during(detectedActivityFence); // Register the fence to receive callbacks. Awareness.FenceApi.updateFences( mGoogleApiClient, new FenceUpdateRequest.Builder().addFence(fenceKey, fence, mPendingIntent) .build()).setResultCallback(new ResultCallback<Status>() { @Override public void onResult(@NonNull Status status) { if (status.isSuccess()) { Log.i(getClass().getSimpleName(), "Successfully registered."); } else { Log.e(getClass().getSimpleName(), "Could not be registered: " + status); } } }); } // Handle the callback on the Intent. public class FenceReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { FenceState fenceState = FenceState.extract(intent); switch (fenceState.getCurrentState()) { case FenceState.TRUE: Log.i(fenceState.getFenceKey(), "Active"); break; case FenceState.FALSE: Log.i(fenceState.getFenceKey(), "Not Active"); break; } } } }
This sample is only for detecting driving state, but, you can call 'createFence' with other activity methods such as :
createFence(DetectedActivityFence.TILTING, "TiltingFence"); createFence(DetectedActivityFence.WALKING, "WalkingFence"); createFence(DetectedActivityFence.ON_FOOT, "OnFootFence"); createFence(DetectedActivityFence.RUNNING, "RunningFence");
回答3:
You can use DetectActivity to differentiates between predefined types of activities.
回答4:
Take a look at the Google Location and Activity Recognition API. I think that's exactly what your looking for.
来源:https://stackoverflow.com/questions/27058741/detect-user-activity-running-cycling-driving-using-android