Detect user activity (running, cycling, driving) using Android

You can use DetectActivity to differentiates between predefined types of activities.


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/guide/topics/location/transitions

http://developer.android.com/training/location/activity-recognition.html


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 :

  1. 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.
  2. 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.

  3. 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");