Bugs Buggy
Bugs Buggy

Reputation: 1546

ActivityRecognitionService (Google API) is not working properly

I have developed my application using this tutorial: http://code.tutsplus.com/tutorials/how-to-recognize-user-activity-with-activity-recognition--cms-25851

Even though I request updates every 3 seconds (or for a change, 5 seconds, 10 seconds etc); the timing of the generated values is highly inconsistent. At times it would generate 4 values in 10 minutes! Why is the API being so inconsistent? Also, I'm unable to disconnect the API, even after I call API.disconnect(), I still keep getting values in logcat, which heats up the phone and consumes battery excessively.

Here is the full project: https://github.com/AseedUsmani/MotionAnalyser2

Basic Code:

1) Activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_analysing);
    mApiClient = new GoogleApiClient.Builder(this)
                .addApi(ActivityRecognition.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
   mStartButton = (Button) findViewById(R.id.startButton);
   mFinishButton = (Button) findViewById(R.id.finishButton);
   mStartButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //resetting counter 
             for (int j = 0; j < 8; j++) {
                    mCount[j] = 0;
                }
                mServiceCount = 0;
                mApiClient.connect();
                mStartButton.setVisibility(View.INVISIBLE);
                mFinishButton.setVisibility(View.VISIBLE);
             }
        }
   mFinishButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mApiClient.disconnect();
}
}
}
@Override
    public void onConnected(@Nullable Bundle bundle) {
        Intent intent = new Intent(this, ActivityRecognizedService.class);
        PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
                 ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mApiClient, 3000, pendingIntent);
    }


@Override
public void onConnectionSuspended(int i) {
    Toast.makeText(AnalysingActivity.this, "Connection to Google Services suspended!", Toast.LENGTH_LONG).show();
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    Toast.makeText(AnalysingActivity.this, "Connection to Google Services failed!", Toast.LENGTH_LONG).show();
}
}

2) Service:

public class ActivityRecognizedService extends IntentService {

AnalysingActivity mObject = new AnalysingActivity();
int confidence;


public ActivityRecognizedService() {
    super("ActivityRecognizedService");
}

public ActivityRecognizedService(String name) {
    super(name);
}

@Override
protected void onHandleIntent(Intent intent) {
    if (ActivityRecognitionResult.hasResult(intent)) {
        ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
        handleDetectedActivities(result.getProbableActivities());
    }
}

private void handleDetectedActivities(List<DetectedActivity> probableActivities) {
    confidence = mObject.confidence;
    mObject.mServiceCount++;

    for (DetectedActivity activity : probableActivities) {
        switch (activity.getType()) {
            case DetectedActivity.IN_VEHICLE: {
                if (activity.getConfidence() >= confidence) {
                    mObject.mCount[0]++;
                }
                mObject.mActivity[0] = "In Vehicle: " + Integer.toString(activity.getConfidence()) + " " + Integer.toString(mObject.mCount[0]);
                Log.e("ActivityRecogition", "In Vehicle: " + activity.getConfidence() + " " + Integer.toString(mObject.mCount[0]));
                break;
            }
            case DetectedActivity.ON_BICYCLE: {
                if (activity.getConfidence() >= confidence) {
                    mObject.mCount[1]++;
                }
                mObject.mActivity[1] = "Cycling: " + Integer.toString(activity.getConfidence()) + " " + Integer.toString(mObject.mCount[1]);
                Log.e("ActivityRecogition", "Cycling: " + activity.getConfidence() + " " + Integer.toString(mObject.mCount[1]));
                break;
            }
            case DetectedActivity.ON_FOOT: {
                if (activity.getConfidence() >= confidence) {
                    mObject.mCount[2]++;
                }
                mObject.mActivity[2] = "On Foot: " + Integer.toString(activity.getConfidence()) + " " + Integer.toString(mObject.mCount[2]);
                Log.e("ActivityRecogition", "On foot: " + activity.getConfidence() + " " + Integer.toString(mObject.mCount[2]));
                break;
            }
            case DetectedActivity.RUNNING: {
                if (activity.getConfidence() >= confidence) {
                    mObject.mCount[3]++;
                }
                mObject.mActivity[3] = "Running: " + Integer.toString(activity.getConfidence()) + " " + Integer.toString(mObject.mCount[3]);
                Log.e("ActivityRecogition", "Running: " + activity.getConfidence() + " " + Integer.toString(mObject.mCount[3]));
                break;
            }
            case DetectedActivity.STILL: {
                if (activity.getConfidence() >= confidence) {
                    mObject.mCount[4]++;
                }
                mObject.mActivity[4] = "Still: " + Integer.toString(activity.getConfidence()) + " " + Integer.toString(mObject.mCount[4]);
                Log.e("ActivityRecogition", "Still: " + activity.getConfidence() + " " + Integer.toString(mObject.mCount[4]));
                break;
            }

            case DetectedActivity.WALKING: {
                if (activity.getConfidence() >= confidence) {
                    mObject.mCount[5]++;
                }
                mObject.mActivity[5] = "Walking: " + Integer.toString(activity.getConfidence()) + " " + Integer.toString(mObject.mCount[5]);
                Log.e("ActivityRecogition", "Walking: " + activity.getConfidence() + " " + Integer.toString(mObject.mCount[5]));
                break;
            }

            case DetectedActivity.TILTING: {
                if (activity.getConfidence() >= confidence) {
                    mObject.mCount[6]++;
                }
                mObject.mActivity[6] = "Tilting: " + Integer.toString(activity.getConfidence()) + " " + Integer.toString(mObject.mCount[6]);
                Log.e("ActivityRecogition", "Tilting: " + activity.getConfidence() + " " + Integer.toString(mObject.mCount[6]));
                break;
            }

            case DetectedActivity.UNKNOWN: {
                if (activity.getConfidence() >= confidence) {
                    mObject.mCount[7]++;
                }
                mObject.mActivity[7] = "Unknown: " + Integer.toString(activity.getConfidence()) + " " + Integer.toString(mObject.mCount[7]);
                Log.e("ActivityRecogition", "Unknown: " + activity.getConfidence() + " " + Integer.toString(mObject.mCount[7]));
                break;
            }
        }
    }
}
}

Upvotes: 0

Views: 725

Answers (1)

ianhanniballake
ianhanniballake

Reputation: 199805

Per the requestActivityUpdates() documentation:

Activities may be received more frequently than the detectionIntervalMillis parameter if another application has also requested activity updates at a faster rate. It may also receive updates faster when the activity detection service receives a signal that the current activity may change, such as if the device has been still for a long period of time and is then unplugged from a phone charger.

Activities may arrive several seconds after the requested detectionIntervalMillis if the activity detection service requires more samples to make a more accurate prediction.

And

Beginning in API 21, activities may be received less frequently than the detectionIntervalMillis parameter if the device is in power save mode and the screen is off.

Therefore you should not expect calls exactly every 3 seconds, but assume that each call you get is the start of a state change - if you haven't received any callback, it is because nothing has changed.

Also note that the correct call to stop receiving updates is removeActivityUpdates(), passing in the same PendingIntent as you passed into requestActivityUpdates().

Upvotes: 1

Related Questions