Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Fit API for Android - Volodymyr Falendysh

GDG Ternopil
September 20, 2016

Fit API for Android - Volodymyr Falendysh

Fit API for Android - Volodymyr Falendysh

GDG Ternopil

September 20, 2016
Tweet

More Decks by GDG Ternopil

Other Decks in Programming

Transcript

  1. General Requirements • To use the Google Fit APIs, you

    need a Google Account. • Google Fit is available on Android devices with Google Play services 7.0 or higher. • Get an OAuth 2.0 client ID • In the build.gradle add the Google Play services client library as a dependency: apply plugin: 'com.android.application' ... dependencies { compile 'com.google.android.gms:play-services-fitness:9.4.0' } • Connect to the fitness service Fitness.SENSORS_API exposes a unified view of sensor streams on the local device and connected devices, and delivers live events to listeners. Fitness.RECORDING_API enables low-battery, always-on background collection of sensor data into the Google Fit store. Fitness.HISTORY_API lets apps create and manage sessions of user activity. Fitness.SESSIONS_API allows querying and insertion of data in Google Fit. Fitness.BLE_API can be used to work with Bluetooth Low Energy devices. Fitness.CONFIG_API can be used to access custom data types and settings.
  2. How to… public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{

    private static final int REQUEST_OAUTH = 1001; private GoogleApiClient mGoogleApiClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Fitness.SENSORS_API) .addApi(Fitness.BLE_API) .addApi(Fitness.CONFIG_API) .addApi(Fitness.HISTORY_API) .addApi(Fitness.RECORDING_API) .addApi(Fitness.SESSIONS_API) .addApiIfAvailable(Fitness.RECORDING_API)
  3. .useDefaultAccount() .setAccountName("Account Name") .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ)) .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE)) .addScope(new Scope(Scopes.FITNESS_BODY_READ)) .addScope(new

    Scope(Scopes.FITNESS_BODY_READ_WRITE)) .addScope(new Scope(Scopes.FITNESS_LOCATION_READ)) .addScope(new Scope(Scopes.FITNESS_LOCATION_READ_WRITE)) .addScope(new Scope(Scopes.FITNESS_NUTRITION_READ)) .addScope(new Scope(Scopes.FITNESS_NUTRITION_READ_WRITE)) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); mGoogleApiClient.connect(); }
  4. @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { // Error while

    connecting. Try to resolve using the pending intent returned. if (connectionResult.getErrorCode() == FitnessStatusCodes.NEEDS_OAUTH_PERMISSIONS) { try { connectionResult.startResolutionForResult(this, REQUEST_OAUTH); } catch (IntentSender.SendIntentException e) { } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_OAUTH && resultCode == RESULT_OK) { mGoogleApiClient.connect(); } super.onActivityResult(requestCode, resultCode, data); }
  5. @Override public void onConnected(@Nullable Bundle bundle) { Fitness.SensorsApi.findDataSources(mGoogleApiClient, new DataSourcesRequest.Builder()

    .setDataTypes(DataType.TYPE_HEART_RATE_BPM) .setDataSourceTypes(DataSource.TYPE_RAW) .setDataSourceTypes(DataSource.TYPE_DERIVED) .build()) .setResultCallback(new ResultCallback<DataSourcesResult>() { @Override public void onResult(@NonNull DataSourcesResult dataSourcesResult) { for (DataSource dataSource : dataSourcesResult.getDataSources()){ dataSource.getDataType(); dataSource.getDevice().getManufacturer(); dataSource.getDevice().getModel(); dataSource.getDevice().getUid(); dataSource.getDevice().getVersion(); dataSource.getName(); dataSourceList.add(dataSource); if (dataSource.getDataType().equals(DataType.TYPE_HEART_RATE_BPM)){ registerHeartRateBPMListener(dataSource);
  6. public void registerHeartRateBPMListener(DataSource dataSource){ Fitness.SensorsApi.add(mGoogleApiClient, new SensorRequest.Builder() .setDataSource(dataSource) .setTimeout(100, TimeUnit.MILLISECONDS)

    .setSamplingRate(1,TimeUnit.MILLISECONDS) .setMaxDeliveryLatency(10,TimeUnit.MILLISECONDS) .setFastestRate(10,TimeUnit.MICROSECONDS) .build(),heartRateBPMListener).setResultCallback(new ResultCallback<Status>() { @Override public void onResult(@NonNull Status status) { if (status.isSuccess()){ Toast.makeText(getApplicationContext(),"Heart Rate Listener registered",Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(),"Heart Rate Listener NOT registered",Toast.LENGTH_SHORT).show(); } }
  7. public OnDataPointListener heartRateBPMListener = new OnDataPointListener() { @Override public void

    onDataPoint(DataPoint dataPoint) { for (Field field : dataPoint.getDataType().getFields()){ field.getName(); Value value = dataPoint.getValue(field); value.asString(); value.asFloat(); value.asInt(); }
  8. Data Type Name Description Permission Fields (Format—Unit) com.google.activity.segment Continuous time

    interval of a single activity. Activity activity (int—enum) com.google.calories.expended Total calories expended over a time interval. Activity calories (float—kcal) com.google.cycling .pedaling.cadence Instantaneous pedaling rate in crank revolutions per minute. Activity rpm (float—rpm) com.google.cycling .wheel_revolution.rpm Instantaneous wheel speed. Location rpm (float—rpm) com.google.distance.delta Distance covered since the last reading. Location distance (float—meters) com.google.heart_rate.bpm Heart rate in beats per minute. Body bpm (float—bpm) com.google.height The user's height, in meters. Body height (float—meters) com.google.location.sample The user's current location. Location latitude (float—degrees) longitude (float—degrees) accuracy (float—meters) altitude (float—meters) com.google.nutrition Food item information Nutrition nutrients (Map<String, float>—calories/grams/IU ) meal_type (int—enum) food_item (String—n/a) com.google.power.sample Instantaneous power generated while performing an activity. Activity watts (float—watts) com.google.speed Instantaneous speed over ground. Location speed (float—m/s) com.google.step_count.cadence Instantaneous cadence in steps per minute. Activity rpm (float—steps/min) com.google.step_count.delta Number of new steps since the last reading. Activity steps (int—count) com.google.weight The user's weight. Body weight (float—kg) com.google.activity.exercise A user's continuous workout routine. Activity exercise (int—enum) repetitions (int—count) resistance type (int—enum) resistance (float—kg) duration (int—milliseconds)
  9. Data Type Name Description Permission Fields (Format—Unit) com.google.activity.summary Total time

    and number of segments in a particular activity for a time interval. Activity activity (int—enum) duration (int—ms) num_segments (int—count) com.google.heart_rate.summary Average, maximum, and minimum beats per minute for a time interval. Body average (float—bpm) max (float—bpm) min (float—bpm) com.google.location.bounding_box A bounding box for the user's location over a time interval. Location low_latitude (float—degrees) low_longitude (float—degrees) high_latitude (float—degrees) high_longitude (float—degrees) com.google.nutrition.summary User's nutrition intake during a time interval. Nutrition nutrients (Map<String,float>—calories/gra ms/IU) meal_type (int—enum) food_item (String—n/a) com.google.power.summary Average, maximum, and minimum power generated while performing an activity. Activity average (float—watts) max (float—watts) min (float—watts) com.google.speed.summary Average, maximum, and minimum speed over ground over a time interval. Location average (float—m/s) max (float—m/s) min (float—m/s) com.google.weight.summary Average, maximum, and minimum weight over a time interval. Body average (float—kg) max (float—kg) min (float—kg)