HB Blog 163: Calculate Users Steps Using Google Fit Api.
The Google Fit APIs for Android are part of Google Play services and consists of these APIs:
The Sensors API provides access to raw sensor data streams from sensors available on the Android device and from sensors available in companion devices, such as wearables.
The Recording API provides automated storage of fitness data using subscriptions. Google Fit stores fitness data of the specified types in the background and persists app subscriptions.
Figure 1: Google Fit on Android.
The History API provides access to the fitness history and lets apps perform bulk operations, like inserting, deleting, and reading fitness data. Apps can also import batch data into Google Fit.
The Sessions API provides functionality to store fitness data with session metadata. Sessions represent a time interval during which users perform a fitness activity.
The Goals API provides a way to track the goals the user has set for their health and fitness progress.
The Bluetooth Low Energy API provides access to Bluetooth Low Energy sensors in Google Fit. This API enables your app to look for available BLE devices and to store data from them in the fitness store.
The Config API provides custom data types and additional settings for Google Fit. For more information, see Custom Data Types andDisconnect from Google Fit.
Google Fit also provides simple access to the daily total of a specified data type. Use the HistoryClient.readDailyTotal() method to retrieve the data type that you specify as of midnight of the current day in the device's current timezone. For example, pass in the TYPE_STEP_COUNT_DELTA data type to this method to retrieve the daily total steps.
package com.harshalbenake.fitnesss;importandroid.app.Notification;importandroid.app.NotificationManager;importandroid.app.PendingIntent;importandroid.content.BroadcastReceiver;importandroid.content.Context;importandroid.content.Intent;importandroid.content.IntentFilter;importandroid.content.IntentSender;importandroid.graphics.Bitmap;importandroid.os.AsyncTask;importandroid.os.Bundle;importandroid.support.annotation.NonNull;importandroid.support.v4.app.NotificationCompat;importandroid.support.v4.app.NotificationManagerCompat;importandroid.support.v4.content.LocalBroadcastManager;importandroid.support.v7.app.AppCompatActivity;importandroid.util.Log;importandroid.widget.TextView;importcom.google.android.gms.common.ConnectionResult;importcom.google.android.gms.common.GooglePlayServicesUtil;importcom.google.android.gms.common.Scopes;importcom.google.android.gms.common.api.GoogleApiClient;importcom.google.android.gms.common.api.PendingResult;importcom.google.android.gms.common.api.Scope;importcom.google.android.gms.fitness.Fitness;importcom.google.android.gms.fitness.data.DataSet;importcom.google.android.gms.fitness.data.DataType;importcom.google.android.gms.fitness.data.Field;importcom.google.android.gms.fitness.result.DailyTotalResult;importcom.google.android.gms.location.ActivityRecognition;importjava.util.concurrent.TimeUnit;publicclassMainActivityextends AppCompatActivity {publicstaticfinal String TAG ="googlefit";privatestaticfinalint REQUEST_OAUTH =1000;privateboolean authInProgress =false;private GoogleApiClient mClient =null;public TextView mtv_logs;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mtv_logs =(TextView) findViewById(R.id.tv_logs);
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,newIntentFilter(TAG));// Create the Google API Client
mClient =new GoogleApiClient.Builder(this).addApi(Fitness.HISTORY_API).addApi(Fitness.CONFIG_API).addApi(ActivityRecognition.API).addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ)).useDefaultAccount().addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks(){@OverridepublicvoidonConnected(Bundle bundle){//Async To fetch stepsnewFetchStepsAsync().execute();}@OverridepublicvoidonConnectionSuspended(int i){// If your connection to the sensor gets lost at some point,// you'll be able to determine the reason and react to it here.if(i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST){
Log.i(TAG,"Connection lost. Cause: Network Lost.");}elseif(i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED){
Log.i(TAG,"Connection lost. Reason: Service Disconnected");}}}).addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener(){@OverridepublicvoidonConnectionFailed(@NonNull ConnectionResult result){// Called whenever the API client fails to connect.
Log.i(TAG,"Connection failed. Cause: "+ result.toString());if(!result.hasResolution()){// Show the localized error dialog
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
MainActivity.this,0).show();return;}// The failure has a resolution. Resolve it.// Called typically when the app is not yet authorized, and an// authorization dialog is displayed to the user.if(!authInProgress){try{
Log.i(TAG,"Attempting to resolve failed connection");
authInProgress =true;
result.startResolutionForResult(MainActivity.this, REQUEST_OAUTH);}catch(IntentSender.SendIntentException e){
Log.e(TAG,"Exception while starting resolution activity", e);}}}}).build();
mClient.connect();}@OverrideprotectedvoidonDestroy(){// Unregister since the activity is about to be closed.
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);super.onDestroy();}privateclassFetchStepsAsyncextends AsyncTask<Object, Object, Long>{protected Long doInBackground(Object... params){long total =0;
PendingResult<DailyTotalResult> result = Fitness.HistoryApi.readDailyTotal(mClient, DataType.TYPE_STEP_COUNT_DELTA);
DailyTotalResult totalResult = result.await(30, TimeUnit.SECONDS);if(totalResult.getStatus().isSuccess()){
DataSet totalSet = totalResult.getTotal();if(totalSet !=null){
total = totalSet.isEmpty()?0: totalSet.getDataPoints().get(0).getValue(Field.FIELD_STEPS).asInt();}}else{
Log.w(TAG,"There was a problem getting the step count.");}return total;}@OverrideprotectedvoidonPostExecute(Long aLong){super.onPostExecute(aLong);//Total steps covered for that day
Log.i(TAG,"Total steps: "+ aLong);
mtv_logs.setText(mtv_logs.getText().toString()+"Total steps: "+ aLong);newFetchCalorieAsync().execute();}}privateclassFetchCalorieAsyncextends AsyncTask<Object, Object, Float>{protected Float doInBackground(Object... params){float total =0;try{
PendingResult<DailyTotalResult> result = Fitness.HistoryApi.readDailyTotal(mClient, DataType.TYPE_CALORIES_EXPENDED);
DailyTotalResult totalResult = result.await(30, TimeUnit.SECONDS);if(totalResult.getStatus().isSuccess()){
DataSet totalSet = totalResult.getTotal();if(totalSet !=null){
total = totalSet.getDataPoints().get(0).getValue(Field.FIELD_CALORIES).asFloat();}}else{
Log.w(TAG,"There was a problem getting the calories.");}}catch(Exception e){
e.printStackTrace();}return total;}@OverrideprotectedvoidonPostExecute(Float aLong){super.onPostExecute(aLong);//Total calories burned for that day
Log.i(TAG,"Total calories: "+ aLong);
mtv_logs.setText(mtv_logs.getText().toString()+"\n"+"Total calories: "+ aLong);
Intent intent =new Intent(MainActivity.this, ActivityRecognizedService.class);
PendingIntent pendingIntent = PendingIntent.getService(MainActivity.this,0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mClient,10, pendingIntent );}}// Our handler for received Intents. This will be called whenever an Intent// with an action named "custom-event-name" is broadcasted.private BroadcastReceiver mMessageReceiver =new BroadcastReceiver(){@OverridepublicvoidonReceive(Context context, Intent intent){// Get extra data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver","Got message: "+ message);
mtv_logs.setText(mtv_logs.getText().toString()+"\n"+ message);
displayNotification(mtv_logs.getText().toString());}};privatevoiddisplayNotification(String strMessage){
NotificationCompat.Builder mBuilder =new NotificationCompat.Builder(MainActivity.this).setSmallIcon(R.drawable.ic_launcher_round).setContentTitle("Fitness").setContentText(strMessage).setAutoCancel(true).setDefaults(Notification.DEFAULT_SOUND).setPriority(Notification.PRIORITY_HIGH);
mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(strMessage));
NotificationManager mNotificationManager=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);// my_notification_idallows you to update the displayNotification later on.
mNotificationManager.notify(1, mBuilder.build());}}
No comments:
Post a Comment