14

I am working on demo application to get current activity sample using Google Fit. I can get Speed as well as Distance correctly. But it is not returning "in_vehicle" or "biking" state very frequently though I was in the same state. Find attached screenshot for the same. I got speed 59.40KM/H(36.91 M/h) and at that time it not returned "in_vehicle" activity state.

Please provide solution/feedback for the same.

Code :

@Override
 public void onDataPoint(DataPoint dataPoint) {
     for (Field field : dataPoint.getDataType().getFields()) {
        Value val = dataPoint.getValue(field);
           if(field.getName().trim().toLowerCase().equals("activity"))
                    {
                        if(FitnessActivities.getName(Integer.parseInt(val.toString())).equals("biking"))
                        {
                            strState = "Cycling";
                        }
                        else if(FitnessActivities.getName(Integer.parseInt(val.toString())).equals("in_vehicle"))
                        {
                            strState = "Automotive";
                        }
                        else if(FitnessActivities.getName(Integer.parseInt(val.toString())).equals("walking"))
                        {
                            strState = "Walking";
                        }
                        else
                        {
                            strState = "Not Moving";
                        }
                    }
            }
}

Thanks.

IMAGE

steve
  • 1,365
  • 4
  • 19
  • 33
  • piece of code would we better to understand . – dharmendra Sep 03 '15 at 10:49
  • You should edit the title and body of your question to indicate that "activity" is not referring to "android.app.Activity", but rather to the "fitness activity" String. – Jared Rummler Sep 07 '15 at 06:30
  • Would you post the code on how you trigger Google API to send this `DataPoint` object? The way you do this seems far from what I know on how `ActivityRecognitionApi` should be used. Would you want a sample project instead? – Derek Fung Sep 09 '15 at 06:42
  • @DerekFung : Yes Sample project will help. Kindly do needful. – steve Sep 09 '15 at 10:10
  • Can you log `Log.i(TAG, "Detected DataPoint field: " + field.getName());` and `Log.i(TAG, "Detected DataPoint value: " + val);` inside `onDataPoint` and update values for us to see? Also check BasicSampleAPI sample project https://github.com/googlesamples/android-fit/tree/master/BasicSensorsApi to see if you've followed all the steps – random Sep 09 '15 at 10:12

3 Answers3

4

You can find the sample project I created here.

https://github.com/cyfung/ActivityRecognitionSample

Important note: you may NOT get the data as frequent as you requested!

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.

Key components:

Create the GoogleApiClient in onCreate

mGoogleApiClient =
        new GoogleApiClient.Builder(this).addApi(ActivityRecognition.API)
            .addConnectionCallbacks(this).addOnConnectionFailedListener(this).build();

Connect and disconnect the api client in onStart and onStop as suggested in Google Api documentation.

  @Override
  protected void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
    mStatusView.setText("connecting");
  }

  @Override
  protected void onStop() {
    super.onStop();
    mGoogleApiClient.disconnect();
    mStatusView.setText("disconnected");
  }

Start activity recognition (should not be called before Google Api connect). Use PendingIntent.getService to create pending intent as callback.

final PendingResult<Status>
    statusPendingResult =
    ActivityRecognition.ActivityRecognitionApi
        .requestActivityUpdates(mGoogleApiClient, DETECT_INTERVAL, PendingIntent
            .getService(this, 0, new Intent(this, ActivityDetectionService.class),
                          PendingIntent.FLAG_UPDATE_CURRENT));
statusPendingResult.setResultCallback(this);

IntentService is the standard method suggested to for callback

public class ActivityDetectionService extends IntentService {

  protected static final String TAG = "activityDetectionService";

  public ActivityDetectionService() {
    super(TAG);
  }

  @Override
  protected void onHandleIntent(Intent intent) {
    final ActivityRecognitionResult
        activityRecognitionResult =
        ActivityRecognitionResult.extractResult(intent);
    if (activityRecognitionResult == null) {
      return;
    }

    //process the result here, pass the data needed to the broadcast
    // e.g. you may want to use activityRecognitionResult.getMostProbableActivity(); instead
    final List<DetectedActivity>
        probableActivities =
        activityRecognitionResult.getProbableActivities();

    sendBroadcast(MainActivity.newBroadcastIntent(probableActivities));
  }
}

Register the service in manifest.

    <service
            android:name=".ActivityDetectionService"
            android:exported="false">
    </service>

To use the API, you need add the followings in manifest as well.

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

<meta-data
                android:name="com.google.android.gms.version"
                android:value="@integer/google_play_services_version" />

To get back the data to the activity I used a BroadcastReceiver created in onCreate

mBroadcastReceiver = new BroadcastReceiver() {

  @Override
  public void onReceive(Context context, Intent intent) {
    ...
  }
}

Register and unregister in onResume and onPause respectively.

  @Override
  protected void onResume() {
    super.onResume();
    registerReceiver(mBroadcastReceiver, newBroadcastIntentFilter());
  }

  @Override
  protected void onPause() {
    super.onPause();
    unregisterReceiver(mBroadcastReceiver);
  }
Derek Fung
  • 8,171
  • 1
  • 25
  • 28
1

As you said you are getting speed correctly. You can put customise code written below.

if (strState.equals("Automotive") && speed == 0.00)
{
   strState = "Not Moving";
}
else if (strState.equals("Not Moving") && speed > 5)
{
   strState = "Automotive";
}
else
{
   strState = "strState";
}

This might not be the correct one but It will be give you nearby state result.

Pratik Patel
  • 474
  • 4
  • 20
-1

I'm not familiar with google fit api, so the only advice i can give you is to check your code carefully. Is
Integer.parseInt(val.toString())
returning the right int and can
FitnessActivities.getName()
equal "biking", "walking", "in_vehicle" etc.

As i can see from here: https://developers.google.com/fit/rest/v1/reference/activity-types

Biking, In vehicle and Walking are 0, 1 and 7. Check what FitnessActivities.getName(0) is returning for example, also check is val returning different values or it's returning the same every time.

If you have any problem with your codes you should know what are the code is doing at any line, what methods and functions are returning... Also inform people so they found solutions easier.