Detecting user activity in android can de done very easily using ActivityRecognitionClient. You can detect user activities like Still, Running, Walking, Cycling, Tilting, Driving etc., We can see this API widely used in lot of fitness apps (like GoogleFit) to provide user activity info like number steps he is taken, the distance he is travelled.

This article explains how to fetch user activity using a background service so that the activities can be tracked even when the app is in background.

android-user-activity-recognition-still-walking-running-driving

1. Activity Recognition

Earlier user activity was detected using LocationClient, ActivityRecognitionApi. But these were deprecated recently and now we have to use ActivityRecognitionClient to do the same (hopefully it won’t be deprecated again, but their main intent is providing much efficient api).

Here is code snippet that can be used to detect the activity.

ActivityRecognitionClient mActivityRecognitionClient = new ActivityRecognitionClient(this);

Task<Void> task = mActivityRecognitionClient.requestActivityUpdates(
            Constants.DETECTION_INTERVAL_IN_MILLISECONDS,
            mPendingIntent);

ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
ArrayList<DetectedActivity> detectedActivities = (ArrayList) result.getProbableActivities();

for (DetectedActivity activity : detectedActivities) {
     Log.e(TAG, "Detected activity: " + activity.getType() + ", " + activity.getConfidence());
}

Let’s start this by creating new project in Android Studio.

2. Creating New Project

android-activity-recognition

1. Create a new project in Android Studio from File ⇒ New Project and select Basic Activity from templates.

2. Download this res folder and add the drawables to your project’s res. This folder contains necessary drawables required for this example project.

3. Open build.gradle file and add play-services-location dependency.

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    //...

    compile 'com.google.android.gms:play-services-location:11.6.0'
}

4. Create a class named Constants.java to keep few global variables like activity frequency interval and confidence threshold.

package info.androidhive.activityrecognition;

/**
 * Created by ravi on 17/12/17.
 */

public class Constants {

    public static final String BROADCAST_DETECTED_ACTIVITY = "activity_intent";

    static final long DETECTION_INTERVAL_IN_MILLISECONDS = 30 * 1000;

    public static final int CONFIDENCE = 70;
}

5. Create a class named DetectedActivitiesIntentService.java and extend it from IntentService. In onHandleIntent() method, list of probable activities will be retried and broadcasted using LocalBroadcastManager.

package info.androidhive.activityrecognition;


/**
 * Created by ravi on 16/12/17.
 */

import android.app.IntentService;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity;

import java.util.ArrayList;

public class DetectedActivitiesIntentService  extends IntentService {

    protected static final String TAG = DetectedActivitiesIntentService.class.getSimpleName();

    public DetectedActivitiesIntentService() {
        // Use the TAG to name the worker thread.
        super(TAG);
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void onHandleIntent(Intent intent) {
        ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);

        // Get the list of the probable activities associated with the current state of the
        // device. Each activity is associated with a confidence level, which is an int between
        // 0 and 100.
        ArrayList<DetectedActivity> detectedActivities = (ArrayList) result.getProbableActivities();

        for (DetectedActivity activity : detectedActivities) {
            Log.e(TAG, "Detected activity: " + activity.getType() + ", " + activity.getConfidence());
            broadcastActivity(activity);
        }
    }

    private void broadcastActivity(DetectedActivity activity) {
        Intent intent = new Intent(Constants.BROADCAST_DETECTED_ACTIVITY);
        intent.putExtra("type", activity.getType());
        intent.putExtra("confidence", activity.getConfidence());
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }
}

6. We need to create another background service class named BackgroundDetectedActivitiesService.java which runs in background and triggers the activities in an interval basis.

package info.androidhive.activityrecognition;

import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.location.ActivityRecognitionClient;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;

public class BackgroundDetectedActivitiesService extends Service {
    private static final String TAG = BackgroundDetectedActivitiesService.class.getSimpleName();

    private Intent mIntentService;
    private PendingIntent mPendingIntent;
    private ActivityRecognitionClient mActivityRecognitionClient;

    IBinder mBinder = new BackgroundDetectedActivitiesService.LocalBinder();

    public class LocalBinder extends Binder {
        public BackgroundDetectedActivitiesService getServerInstance() {
            return BackgroundDetectedActivitiesService.this;
        }
    }

    public BackgroundDetectedActivitiesService() {

    }

    @Override
    public void onCreate() {
        super.onCreate();
        mActivityRecognitionClient = new ActivityRecognitionClient(this);
        mIntentService = new Intent(this, DetectedActivitiesIntentService.class);
        mPendingIntent = PendingIntent.getService(this, 1, mIntentService, PendingIntent.FLAG_UPDATE_CURRENT);
        requestActivityUpdatesButtonHandler();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }

    public void requestActivityUpdatesButtonHandler() {
        Task<Void> task = mActivityRecognitionClient.requestActivityUpdates(
                Constants.DETECTION_INTERVAL_IN_MILLISECONDS,
                mPendingIntent);

        task.addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void result) {
                Toast.makeText(getApplicationContext(),
                        "Successfully requested activity updates",
                        Toast.LENGTH_SHORT)
                        .show();
            }
        });

        task.addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(getApplicationContext(),
                        "Requesting activity updates failed to start",
                        Toast.LENGTH_SHORT)
                        .show();
            }
        });
    }

    public void removeActivityUpdatesButtonHandler() {
        Task<Void> task = mActivityRecognitionClient.removeActivityUpdates(
                mPendingIntent);
        task.addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void result) {
                Toast.makeText(getApplicationContext(),
                        "Removed activity updates successfully!",
                        Toast.LENGTH_SHORT)
                        .show();
            }
        });

        task.addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(getApplicationContext(), "Failed to remove activity updates!",
                        Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        removeActivityUpdatesButtonHandler();
    }
}

7. Open AndroidManifest.xml and add ACTIVITY_RECOGNITION permission. Also add DetectedActivitiesIntentService and BackgroundDetectedActivitiesService services.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.androidhive.activityrecognition">

    <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Service that provides activity recognition data. Setting the android:exported attribute
        to "false" stops other apps from starting this service, even when using an explicit
        intent. -->
        <service
            android:name=".DetectedActivitiesIntentService"
            android:exported="false" />

        <service android:name=".BackgroundDetectedActivitiesService"></service>
    </application>

</manifest>

3. Receiving Activity Updates

Now we have everything ready. Let’s see how to receive the user activity updates in main activity or in any other activity.

8. Open the layout file main activity (activity_main.xml) and below layout code. Here we are adding an ImageView (to display an icon representing the activity) and TextView (to display the activity). We also need two buttons to start and start the activity recognition service.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context="info.androidhive.activityrecognition.MainActivity">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/img_activity"
            android:layout_width="wrap_content"
            android:layout_height="200dp"
            android:tint="#606060" />

        <TextView
            android:id="@+id/txt_activity"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:textAllCaps="true"
            android:textColor="@color/colorPrimary"
            android:textSize="18dp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/txt_confidence"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="10dp"
            android:textAllCaps="true"
            android:textSize="14dp" />

    </LinearLayout>

    <Button
        android:id="@+id/btn_start_tracking"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:text="Start Tracking" />

    <Button
        android:id="@+id/btn_stop_tracking"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:text="Stop Tracking" />
</RelativeLayout>

9. Finally open MainActivity.java and do the below necessary changes.

> startTracking() and stopTracking() methods start or stops the user activity updates by toggling the service state.

> BroadcastReceiver is used to receive the activity updates from the IntentService.

> handleUserActivity() receives the user activity updates and displays the information on UI when the confidence value exceeds the threshold confidence value.

> In onResume() and onPause() methods the local broadcast receiver is registered and removed.

package info.androidhive.activityrecognition;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.android.gms.location.DetectedActivity;

public class MainActivity extends AppCompatActivity {

    private String TAG = MainActivity.class.getSimpleName();
    BroadcastReceiver broadcastReceiver;

    private TextView txtActivity, txtConfidence;
    private ImageView imgActivity;
    private Button btnStartTrcking, btnStopTracking;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtActivity = findViewById(R.id.txt_activity);
        txtConfidence = findViewById(R.id.txt_confidence);
        imgActivity = findViewById(R.id.img_activity);
        btnStartTrcking = findViewById(R.id.btn_start_tracking);
        btnStopTracking = findViewById(R.id.btn_stop_tracking);

        btnStartTrcking.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startTracking();
            }
        });

        btnStopTracking.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                stopTracking();
            }
        });

        broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals(Constants.BROADCAST_DETECTED_ACTIVITY)) {
                    int type = intent.getIntExtra("type", -1);
                    int confidence = intent.getIntExtra("confidence", 0);
                    handleUserActivity(type, confidence);
                }
            }
        };

        startTracking();
    }

    private void handleUserActivity(int type, int confidence) {
        String label = getString(R.string.activity_unknown);
        int icon = R.drawable.ic_still;

        switch (type) {
            case DetectedActivity.IN_VEHICLE: {
                label = getString(R.string.activity_in_vehicle);
                icon = R.drawable.ic_driving;
                break;
            }
            case DetectedActivity.ON_BICYCLE: {
                label = getString(R.string.activity_on_bicycle);
                icon = R.drawable.ic_on_bicycle;
                break;
            }
            case DetectedActivity.ON_FOOT: {
                label = getString(R.string.activity_on_foot);
                icon = R.drawable.ic_walking;
                break;
            }
            case DetectedActivity.RUNNING: {
                label = getString(R.string.activity_running);
                icon = R.drawable.ic_running;
                break;
            }
            case DetectedActivity.STILL: {
                label = getString(R.string.activity_still);
                break;
            }
            case DetectedActivity.TILTING: {
                label = getString(R.string.activity_tilting);
                icon = R.drawable.ic_tilting;
                break;
            }
            case DetectedActivity.WALKING: {
                label = getString(R.string.activity_walking);
                icon = R.drawable.ic_walking;
                break;
            }
            case DetectedActivity.UNKNOWN: {
                label = getString(R.string.activity_unknown);
                break;
            }
        }

        Log.e(TAG, "User activity: " + label + ", Confidence: " + confidence);

        if (confidence > Constants.CONFIDENCE) {
            txtActivity.setText(label);
            txtConfidence.setText("Confidence: " + confidence);
            imgActivity.setImageResource(icon);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver,
                new IntentFilter(Constants.BROADCAST_DETECTED_ACTIVITY));
    }

    @Override
    protected void onPause() {
        super.onPause();

        LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
    }

    private void startTracking() {
        Intent intent1 = new Intent(MainActivity.this, BackgroundDetectedActivitiesService.class);
        startService(intent1);
    }

    private void stopTracking() {
        Intent intent = new Intent(MainActivity.this, BackgroundDetectedActivitiesService.class);
        stopService(intent);
    }
}

Now run the app and test it once. You might want to Walk, Run or Drive if want to see other states.

android-user-activity-recognition
Subscribe
Notify of
guest
63 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Akkis
3 years ago

Wow! Thank you so much Ravi!

Ravi Tamada
3 years ago
Reply to  Akkis

You are welcome 😀

Ziigic
Ziigic
3 years ago

Always awesome..

Ravi Tamada
3 years ago
Reply to  Ziigic

Thank you 🙂

Abdul Mannan
3 years ago

Awsome 😉

Ravi Tamada
3 years ago
Reply to  Abdul Mannan

Thank you 🙂

Jatin Mandanka
3 years ago

Awesome… Great job.

Ravi Tamada
3 years ago
Reply to  Jatin Mandanka

Thank you

Sonu
Sonu
3 years ago

Very informative

Ravi Tamada
3 years ago
Reply to  Sonu

Thank you 🙂

Mehul Kanzariya
Mehul Kanzariya
3 years ago

Hey, whenever I double-click on the code part it starts an infinite loop and goes on expanding with blank space. May there is a bug with your plugin which formats the code. Have a look! Btw, superb article.

Ravi Tamada
3 years ago

Mine is working fine. Meanwhile you can just drag and select the code. Thanks for informing me.

yathavan yogarajah
yathavan yogarajah
3 years ago

Awsome 🙂 , Can i detect walking or bike driving distance by this api?

Ravi Tamada
3 years ago

Yes, you have to write the logic when the user activity state changed. Let’s say when the activity is changed to driving, start a timer to track how much time he drove. To find out the distance he travelled, you might wanna consider location data too. (It won’t be accurate though)

Cüneyt Çarıkçı
Cüneyt Çarıkçı
3 years ago

Thank you Ravi! It is really helpful.

Ravi Tamada
3 years ago

cool 🙂

Jankari Hindi
Jankari Hindi
3 years ago
Reply to  Ravi Tamada

Sir Ravi Please Help Me I wants to Download Visual Composer in Free for website developing please give me way to download visual compoer in free please replay my please

Jankari Hindi
Jankari Hindi
3 years ago

Sir Ravi Please Help Me I wants to Download Visual Composer in Free for website developing please give me way to download visual compoer in free please replay my please

Mayuresh Khare
Mayuresh Khare
3 years ago
Reply to  Jankari Hindi

https://visualcomposer.io/download/
You may find this link useful

Vikas Tomar
Vikas Tomar
3 years ago

Can you please explain the flow of the program. I’m getting confused. Details would be appreciated.
Thanks.

Swarup Das
Swarup Das
3 years ago

Is this client free to use for unlimited users?

Ravi Tamada
3 years ago
Reply to  Swarup Das

There are no limitations. (Users concept shouldn’t raised here and it’s unrelated. Let’s me know if you still have any doubts).

asif ahmed
asif ahmed
3 years ago

(out of topic) I’m just posting this to THANK YOU for all your blog and support. I remember 4 years back when I was fresher and struggling so hard to build one app with no support. Remember I use to follow the steps of your blog to complete my daily task. Which was clean and clear to understand and of course still it is same. After a long time I came back to your site and learnt a new thing today. Thank you for everything brother. Keep posting and keep growing. Asif

Ravi Tamada
3 years ago
Reply to  asif ahmed

Thanks Asif for your kind words and great support 🙂

Trey Rosius
Trey Rosius
3 years ago

Great Post Ravi. I wish to know the plugin you use to lay-out your code fragments here.If you don’t mind.

Ravi Tamada
3 years ago
Reply to  Trey Rosius

Hi Trey

I use SyntaxHighlighter plugin to format my code.
https://wordpress.org/plugins/syntaxhighlighter/

Trey Rosius
Trey Rosius
3 years ago
Reply to  Ravi Tamada

merci boss

Akash Mishra
Akash Mishra
3 years ago

Is it possible to track activity of another device?
Like me and my friend installed this app and with any connection (may be friend request, followers or any other they connected). So can I see my friends activity on my device, when he is running or walking or still. Is it possible?

Winsant surat
3 years ago
Reply to  Akash Mishra

yes.. its possible.. whenever user driving or running, you can send his status to server and send push notification to that user’s follower.., or else make public status for that user. so other user can see what he’s doing by opening his profile.

arti thakur
arti thakur
3 years ago

Hi.. thanks for the great post. Following your post i created a assessebilityService which is tracking user’s activity. I am trying to log the activity for every 1 sec. But it’s logging the activity in every 1 min. The app is for android wear.
Code:
public class MovementSensorService extends AccessibilityService {
private static final String TAG = “MovementSensorService”;
BroadcastReceiver broadcastReceiver;
//private Intent mIntentService;
private PendingIntent mPendingIntent;
private ActivityRecognitionClient mActivityRecognitionClient;
static final long DETECTION_INTERVAL_IN_MILLISECONDS = 1 * 1000;

public static class MyServiceHandler extends IntentService {
public MyServiceHandler() {
super(“ActivityRecognitionIntentService”);
}

protected void onHandleIntent(Intent intent) {
Log.i(TAG, “inside handler”);
if(ActivityRecognitionResult.hasResult(intent)) {
Log.i(TAG, “intent: ” +ActivityRecognitionResult.hasResult(intent));
//Extract the result from the Response
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
ArrayList detectedActivity = (ArrayList) result.getProbableActivities();

//Get the Confidence and Name of Activity
for (DetectedActivity activity : detectedActivity) {
int confidence = activity.getConfidence();
String mostProbableName = getActivityName(activity.getType());
//Fire the intent with activity name & confidence
Intent i = new Intent(“ImActive”);
i.putExtra(“activity”, mostProbableName);
i.putExtra(“confidence”, confidence);

Log.d(TAG, “Most Probable Name : ” + mostProbableName);
Log.d(TAG, “Confidence : ” + confidence);

//Send Broadcast to be listen in MainActivity
LocalBroadcastManager.getInstance(this).sendBroadcast(i);
}

}else {
Log.d(TAG, “Intent had no data returned”);
}
}
//Get the activity name
private String getActivityName(int type) {
switch (type)
{
case DetectedActivity.IN_VEHICLE:
return “In Vehicle”;
case DetectedActivity.ON_BICYCLE:
return “On Bicycle”;
case DetectedActivity.ON_FOOT:
return “On Foot”;
case DetectedActivity.WALKING:
return “Walking”;
case DetectedActivity.STILL:
return “Still”;
case DetectedActivity.TILTING:
return “Tilting”;
case DetectedActivity.RUNNING:
return “Running”;
case DetectedActivity.UNKNOWN:
return “Unknown”;
}
return “N/A”;
}
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

}

//fun to check if activity update is success or fail
public void requestActivityUpdatesButtonHandler() {
Task task = mActivityRecognitionClient.requestActivityUpdates(
DETECTION_INTERVAL_IN_MILLISECONDS,
mPendingIntent);

task.addOnSuccessListener(new OnSuccessListener() {
@Override
public void onSuccess(Void result) {
Toast.makeText(getApplicationContext(),
“Successfully requested activity updates”,
Toast.LENGTH_SHORT)
.show();
}
});

task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(getApplicationContext(),
“Requesting activity updates failed to start”,
Toast.LENGTH_SHORT)
.show();
}
});
}
@Override
protected void onServiceConnected() {
// Create an overlay and display the action bar
//used to create the view for assessiblity service
//we can do initialisations and call other methods from here
Log.i(TAG, “inside onServiceConnected”);
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(“ImActive”)) {
String type = intent.getStringExtra(“activity”);
int confidence = intent.getIntExtra(“confidence”, 0);
Calendar rightNow = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(“h:mm:ss a”);
String strDate = sdf.format(rightNow.getTime());
String v = strDate + ” ” +
type + ” ” +
“Confidence : ” + confidence + “n”;
Log.d(TAG, v);

// Toast.makeText(getApplicationContext(),
// “activity: “+ type+”and confidence:” + confidence,
// Toast.LENGTH_SHORT)
// .show();
}
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver,
new IntentFilter(“ImActive”));
mActivityRecognitionClient = new ActivityRecognitionClient(this);
Intent i = new Intent(this, MyServiceHandler.class);
mPendingIntent = PendingIntent
.getService(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);

//Log.d(TAG, “connected to ActivityRecognition”);
requestActivityUpdatesButtonHandler();

}

@Override
public void onInterrupt() {

}
@Override
public void onDestroy() {
super.onDestroy();
removeActivityUpdatesButtonHandler();
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
}

//unregistering pendingIntent if user kills the service
public void removeActivityUpdatesButtonHandler() {
Task task = mActivityRecognitionClient.removeActivityUpdates(
mPendingIntent);
task.addOnSuccessListener(new OnSuccessListener() {
@Override
public void onSuccess(Void result) {
Toast.makeText(getApplicationContext(),
“Removed activity updates successfully!”,
Toast.LENGTH_SHORT)
.show();
}
});

task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(getApplicationContext(), “Failed to remove activity updates!”,
Toast.LENGTH_SHORT).show();
}
});
}
}

ian wanderson
ian wanderson
3 years ago

fine

yohan dhanushka fernando
yohan dhanushka fernando
3 years ago

awesome..thank you sir.

Ravi Tamada
3 years ago

You are welcome 🙂

Rathod_brinda29@gmail.com Pink
Rathod_brinda29@gmail.com Pink
3 years ago

cant resolve ActivityRecognitionClient

chiruraja
chiruraja
3 years ago

you have really a great stuff…..delighted sir…happy for you….

Michael_O
Michael_O
3 years ago

This was super helpful :disqus , thank you! But why add the second service, BackgroundDetectedActivitiesService? The solution seems to work fine without it as an intermediary between MainActivity and DetectedActivitiesIntentService.

Ravi Tamada
3 years ago
Reply to  Michael_O

This is to detect the activity even when all is in background.

Ravi Tamada
3 years ago

Thanks for the tip.

Ravi Tamada
3 years ago

Android considers batter optimization to be primary concern. So frequent updates might not be possible.

Sunil Kumar
Sunil Kumar
3 years ago

Hello Ravi Tamada Sir,

Could please tell me why all switch cases are running and when i moving my mobile and walking its not updating the state, what is the issue behind this?

And i have change the interval to 1000 but it is not considering this time interval.

Hope i will get my answer
Thank you

Nedson Soares
Nedson Soares
2 years ago

I like your idea, but it’s not working. When I implemented, I put a breakpoint in “public int compare (DetectedActivity o1, DetectedActivity o2)”, that line is not running. Why?

Bono Vox (SethM3'P)
Bono Vox (SethM3'P)
2 years ago

as always perfect …. greats from Poland :] master Ravi … tHX

Ravi Tamada
2 years ago

Thanks Bono 🙂

Lord Ryotopic
Lord Ryotopic
2 years ago

Wonderful. Thanks a lot for sharing this

Ravi Tamada
2 years ago
Reply to  Lord Ryotopic

You are welcome Lord 🙂

abhijit thorat
abhijit thorat
2 years ago

Hello Sir,

I need to implement the activity recognition in an app which will detect the activity even after user removes the application from background (Similar to fitness app). I am tr
ying this using background services but still can’t get it done. The service keeps on stopping.

Your help will be extremely appreciated. Thanks in advance!

Katasani Venkateswara Reddy
Katasani Venkateswara Reddy
2 years ago
Reply to  abhijit thorat

Hi Abhijit,
Did you find solution? if yes please help me becouse i have same kind of requirement.
Thanks in advance.

abhijit thorat
abhijit thorat
2 years ago

Hello,
Yes I got the solution. I am using Google Activity Recognition api for detecting user’s activity and performing tasks based on that. For this, you will need to create

1. Normal service which will run in background
2. Intent service for Activity Recognition
Normal background service will be always be in background calling activity recognition for activity updates.

RETURN START_STICKY in onStartCommand() of normal service and start the service again in onDestroy() method of normal service.

David Castillo
David Castillo
2 years ago
Reply to  abhijit thorat

Necesito la aplicación para hacerla funcionar en el computador, como me pude ayudar?
Ing. David R. Castillo S.
Docente

abhijit thorat
abhijit thorat
2 years ago
Reply to  David Castillo

Sir, English please. I don’t speak this language

David Castillo
David Castillo
2 years ago
Reply to  abhijit thorat

I need the application to work on the computer, how could I help? email: davecastle73@hotmail.com

abhijit thorat
abhijit thorat
2 years ago
Reply to  David Castillo

Sir, as per my limited knowledge for activity recognition we need set of sensors which gives us data-set for performing machine learning to identify most probable user activity. I have not tried doing it on computer so far, but it can be possible if your computer have sensors like Gyroscope, accelerometer, etc. If possible, I will definitely try ‘doing it and let you know

David Castillo
David Castillo
2 years ago
Reply to  abhijit thorat

Thanks

Ing. David R. Castillo S.
Docente

Amit Parameshwar
Amit Parameshwar
2 years ago
Reply to  abhijit thorat

hey can you please elaborate what you did to run this in the background? Do you have the source code I can refer to?

Trina McLaren
Trina McLaren
2 years ago

thanks but the app didn’t work for me. The START TRACKING button does nothing. (Android 4.4.4 on Samsung Galaxy S3)

David Castillo
David Castillo
2 years ago

I need the application to make it work on the computer, how could I help?

iamandroidhive
iamandroidhive
1 year ago
Reply to  David Castillo

maachoda computer leke bhagega tu bhosadike champu?

bhupendra saini
bhupendra saini
2 years ago

Sir the Start Tracking Button does not work. Please help me for this problem.

sathish kumar
sathish kumar
2 years ago

Whether activity recognition works even when app is in killed state ?

Steven Barry
Steven Barry
2 years ago

Hi, if creating a timer to time the amount of time driving or stationary, how can this be done? thankyou.

Jewel Rana
Jewel Rana
1 year ago

Please help me when application is kill state, detection is not working in android oreo or above.
Advanced Thank you

Drax
Drax
9 months ago

It won’t run if you close the app or minimize the app since you’re literally unregistering the service in onPause method and you’re stopping the services in onStop() method. Remove both of em and if the app is kept in the background it should be good to go. As for recognizing when the app is closed, the doze modes kill the bg services no matter what you do. So this becomes an annoyance factor if you try forcing it by using foreground service.

Rohde
Rohde
11 days ago

Does the app run when the app is in the background or when the phone is off?

63
0
Would love your thoughts, please comment.x
()
x