com.chhavi.envisionproductivity.FitnessActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.chhavi.envisionproductivity.FitnessActivity.java

Source

/*
 * Copyright (C) 2014 Google, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.chhavi.envisionproductivity;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.common.api.Status;
/*import com.google.android.gms.fit.samples.common.logger.Log;
import com.google.android.gms.fit.samples.common.logger.LogView;
import com.google.android.gms.fit.samples.common.logger.LogWrapper;
import com.google.android.gms.fit.samples.common.logger.MessageOnlyLogFilter;*/
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.data.DataPoint;
import com.google.android.gms.fitness.data.DataSource;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.data.Device;
import com.google.android.gms.fitness.data.Field;
import com.google.android.gms.fitness.data.Value;
import com.google.android.gms.fitness.request.DataSourcesRequest;
import com.google.android.gms.fitness.request.OnDataPointListener;
import com.google.android.gms.fitness.request.SensorRequest;
import com.google.android.gms.fitness.result.DataSourcesResult;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * This sample demonstrates how to use the Sensors API of the Google Fit platform to find
 * available data sources and to register/unregister listeners to those sources. It also
 * demonstrates how to authenticate a user with Google Play Services.
 */
public class FitnessActivity extends AppCompatActivity {
    public static final String TAG = "BasicSensorsApi";
    // [START auth_variable_references]
    private GoogleApiClient mClient = null;
    // [END auth_variable_references]

    public static ArrayList<KeyPair> fitnessPairs;
    public static FitnessActivity singletonObject;

    int previousValue = 0;
    private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;

    // [START mListener_variable_reference]
    // Need to hold a reference to this listener, as it's passed into the "unregister"
    // method in order to stop all sensors from sending data to this listener.
    private OnDataPointListener mListener;
    List<KeyPair> gmailLabel;

    // [END mListener_variable_reference]

    public static synchronized FitnessActivity getSingletonObject() {
        if (singletonObject == null) {
            singletonObject = new FitnessActivity();
        }
        return singletonObject;
    }

    // [START auth_oncreate_setup]
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Put application specific code here.

        fitnessPairs = new ArrayList<>();
        setContentView(R.layout.fitness_main);
        // This method sets up our custom logger, which will print all log messages to the device
        // screen, as well as to adb logcat.
        //  initializeLogging();

        // When permissions are revoked the app is restarted so onCreate is sufficient to check for
        // permissions core to the Activity's functionality.

        gmailLabel = new ArrayList<KeyPair>();
        // gmailLabel = (ArrayList<KeyPair>)getIntent().getSerializableExtra("gmailLabel");
        if (!checkPermissions()) {
            requestPermissions();
        }
    }

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

        // This ensures that if the user denies the permissions then uses Settings to re-enable
        // them, the app will start working.
        buildFitnessClient();
    }
    // [END auth_oncreate_setup]

    // [START auth_build_googleapiclient_beginning]
    /**
     *  Build a {@link GoogleApiClient} that will authenticate the user and allow the application
     *  to connect to Fitness APIs. The scopes included should match the scopes your app needs
     *  (see documentation for details). Authentication will occasionally fail intentionally,
     *  and in those cases, there will be a known resolution, which the OnConnectionFailedListener()
     *  can address. Examples of this include the user never having signed in before, or having
     *  multiple accounts on the device and needing to specify which account to use, etc.
     */
    public void buildFitnessClient() {
        if (mClient == null && checkPermissions()) {
            mClient = new GoogleApiClient.Builder(this).addApi(Fitness.SENSORS_API)
                    .addScope(new Scope(Scopes.FITNESS_LOCATION_READ)).addScope(Fitness.SCOPE_ACTIVITY_READ)
                    .addScope(Fitness.SCOPE_BODY_READ_WRITE)
                    .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                        @Override
                        public void onConnected(Bundle bundle) {
                            Log.i(TAG, "Connected!!!");
                            // Now you can make calls to the Fitness APIs.
                            findFitnessDataSources();
                        }

                        @Override
                        public void onConnectionSuspended(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 == ConnectionCallbacks.CAUSE_NETWORK_LOST) {
                                Log.i(TAG, "Connection lost.  Cause: Network Lost.");
                            } else if (i == ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
                                Log.i(TAG, "Connection lost.  Reason: Service Disconnected");
                            }
                        }
                    }).enableAutoManage(this, 0, new GoogleApiClient.OnConnectionFailedListener() {
                        @Override
                        public void onConnectionFailed(ConnectionResult result) {
                            Log.i(TAG, "Google Play services connection failed. Cause: " + result.toString());
                            Toast.makeText(FitnessActivity.this,
                                    "Exception while connecting to Google Play services: "
                                            + result.getErrorMessage(),
                                    Toast.LENGTH_LONG).show();
                        }
                    }).build();
        }
    }
    // [END auth_build_googleapiclient_beginning]

    /**
     * Find available data sources and attempt to register on a specific {@link DataType}.
     * If the application cares about a data type but doesn't care about the source of the data,
     * this can be skipped entirely, instead calling
     *     {@link com.google.android.gms.fitness.SensorsApi
     *     #register(GoogleApiClient, SensorRequest, DataSourceListener)},
     * where the {@link SensorRequest} contains the desired data type.
     */
    private void findFitnessDataSources() {
        // [START find_data_sources]
        // Note: Fitness.SensorsApi.findDataSources() requires the ACCESS_FINE_LOCATION permission.
        Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
                // At least one datatype must be specified.
                .setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE)
                // Can specify whether data type is raw or derived.
                .setDataSourceTypes(DataSource.TYPE_RAW).build())
                .setResultCallback(new ResultCallback<DataSourcesResult>() {
                    @Override
                    public void onResult(DataSourcesResult dataSourcesResult) {
                        Log.i(TAG, "Result: " + dataSourcesResult.getStatus().toString());
                        for (DataSource dataSource : dataSourcesResult.getDataSources()) {
                            Log.i(TAG, "Data source found: " + dataSource.toString());
                            Log.i(TAG, "Data Source type: " + dataSource.getDataType().getName());

                            //Let's register a listener to receive Activity data!
                            if ((dataSource.getDataType().equals(DataType.TYPE_LOCATION_SAMPLE)
                                    || dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_CUMULATIVE))
                                    && mListener == null) {
                                Log.i(TAG, "Data source for LOCATION_SAMPLE found!  Registering.");
                                registerFitnessDataListener(dataSource, dataSource.getDataType());
                            }
                        }
                    }
                });
        /*    Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
            // At least one datatype must be specified.
            .setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE)
                    // Can specify whether data type is raw or derived.
            .setDataSourceTypes(DataSource.TYPE_RAW)
            .build())
            .setResultCallback(new ResultCallback<DataSourcesResult>() {
                @Override
                public void onResult(DataSourcesResult dataSourcesResult) {
                    Log.i(TAG, "Result: " + dataSourcesResult.getStatus().toString());
                    for (DataSource dataSource : dataSourcesResult.getDataSources()) {
                        Log.i(TAG, "Data source found: " + dataSource.toString());
                        Log.i(TAG, "Data Source type: " + dataSource.getDataType().getName());
            
                        //Let's register a listener to receive Activity data!
                        if (dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_CUMULATIVE) && mListener == null) {
                            Log.i(TAG, "Data source for TYPE_STEP_COUNT_CUMULATIVE found!  Registering.");
                            registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_CUMULATIVE);
                        }
                    }
                }
            });*/

        /*   Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
            .setDataTypes(
                    DataType.TYPE_LOCATION_SAMPLE,
                    DataType.TYPE_STEP_COUNT_DELTA,
                    DataType.TYPE_DISTANCE_DELTA,
                    DataType.TYPE_HEART_RATE_BPM )
            .setDataSourceTypes(DataSource.TYPE_RAW, DataSource.TYPE_DERIVED)
            .build())
            .setResultCallback(new ResultCallback() {
                @Override
                public void onResult(DataSourcesResult dataSourcesResult) {
            
                   // datasources.clear();
                    for (DataSource dataSource : dataSourcesResult.getDataSources()) {
                        Device device = dataSource.getDevice();
                        String fields = dataSource.getDataType().getFields().toString();
                 //       datasources.add(device.getManufacturer() + " " + device.getModel() + " [" + dataSource.getDataType().getName() + " " + fields + "]");
            
                        final DataType dataType = dataSource.getDataType();
                        if (    dataType.equals(DataType.TYPE_LOCATION_SAMPLE) ||
                                dataType.equals(DataType.TYPE_STEP_COUNT_DELTA) ||
                                dataType.equals(DataType.TYPE_DISTANCE_DELTA) ||
                                dataType.equals(DataType.TYPE_HEART_RATE_BPM)) {
            
                            Fitness.SensorsApi.add(mClient,
                                    new SensorRequest.Builder()
                                            .setDataSource(dataSource)
                                            .setDataType(dataSource.getDataType())
                                            .setSamplingRate(5, TimeUnit.SECONDS)
                                            .build(),
                                    new OnDataPointListener() {
                                        @Override
                                        public void onDataPoint(DataPoint dataPoint) {
                                            String msg = "onDataPoint: ";
                                            for (Field field : dataPoint.getDataType().getFields()) {
                                                Value value = dataPoint.getValue(field);
                                                msg += "onDataPoint: " + field + "=" + value + ", ";
                                            }
                                            Log.i(TAG, msg);
                                        }
                                    })
                                    .setResultCallback(new ResultCallback() {
                                        @Override
                                        public void onResult(Status status) {
                                            if (status.isSuccess()) {
                                                Log.i(TAG,"Listener for " + dataType.getName() + " registered");
                                            } else {
                                                Lo.show("Failed to register listener for " + dataType.getName());
                                            }
                                        }
                                    });
                        }
                    }
                   // datasourcesListener.onDatasourcesListed();
                }
            });*/
        // [END find_data_sources]
    }

    /**
     * Register a listener with the Sensors API for the provided {@link DataSource} and
     * {@link DataType} combo.
     */
    private void registerFitnessDataListener(DataSource dataSource, DataType dataType) {
        // [START register_data_listener]
        mListener = new OnDataPointListener() {
            @Override
            public void onDataPoint(DataPoint dataPoint) {
                for (Field field : dataPoint.getDataType().getFields()) {
                    Value val = dataPoint.getValue(field);
                    Log.i(TAG, "Detected DataPoint field: " + field.getName());
                    Log.i(TAG, "Detected DataPoint value: " + val);

                    //   Log.i(TAG, "Difference in steps: " + (val.asInt()));

                    previousValue = val.asInt();
                    fitnessPairs.add(new KeyPair("Step Count", val.asInt() + ""));
                    fitnessPairs.add(new KeyPair("Distance Covered", "2km"));
                    fitnessPairs.add(new KeyPair("Calories Burnt", "250"));
                    /*fitnessPairs.add(new KeyPair("Step Count", val.asInt() + ""));*/
                    Log.e("asd", fitnessPairs.get(0).getValue());
                    Intent intent = new Intent(FitnessActivity.this, MyNavigationDrawer.class);
                    intent.putExtra("Fitness", (ArrayList<KeyPair>) fitnessPairs);
                    //   intent.putExtra("gmailLabel", (ArrayList<KeyPair>)gmailLabel);
                    startActivity(intent);
                }
            }
        };

        Fitness.SensorsApi.add(mClient, new SensorRequest.Builder().setDataSource(dataSource) // Optional but recommended for custom data sets.
                .setDataType(dataType) // Can't be omitted.
                .setSamplingRate(10, TimeUnit.SECONDS).build(), mListener)
                .setResultCallback(new ResultCallback<Status>() {
                    @Override
                    public void onResult(Status status) {
                        if (status.isSuccess()) {
                            Log.i(TAG, "Listener registered!");
                        } else {
                            Log.i(TAG, "Listener not registered.");
                        }
                    }
                });
        // [END register_data_listener]
    }

    /**
     * Unregister the listener with the Sensors API.
     */
    private void unregisterFitnessDataListener() {
        if (mListener == null) {
            // This code only activates one listener at a time.  If there's no listener, there's
            // nothing to unregister.
            return;
        }

        // [START unregister_data_listener]
        // Waiting isn't actually necessary as the unregister call will complete regardless,
        // even if called from within onStop, but a callback can still be added in order to
        // inspect the results.
        Fitness.SensorsApi.remove(mClient, mListener).setResultCallback(new ResultCallback<Status>() {
            @Override
            public void onResult(Status status) {
                if (status.isSuccess()) {
                    Log.i(TAG, "Listener was removed!");
                } else {
                    Log.i(TAG, "Listener was not removed.");
                }
            }
        });
        // [END unregister_data_listener]
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        //  getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    /*  @Override
      public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_unregister_listener) {
        unregisterFitnessDataListener();
        return true;
    }
    return super.onOptionsItemSelected(item);
      }*/

    /**
     *  Initialize a custom log class that outputs both to in-app targets and logcat.
     */
    /*
        private void initializeLogging() {
    // Wraps Android's native log framework.
    LogWrapper logWrapper = new LogWrapper();
    // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
    Log.setLogNode(logWrapper);
    // Filter strips out everything except the message text.
    MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
    logWrapper.setNext(msgFilter);
    // On screen logging via a customized TextView.
    LogView logView = (LogView) findViewById(R.id.sample_logview);
        
    // Fixing this lint errors adds logic without benefit.
    //noinspection AndroidLintDeprecation
    logView.setTextAppearance(this, R.style.Log);
        
    logView.setBackgroundColor(Color.WHITE);
    msgFilter.setNext(logView);
    Log.i(TAG, "Ready");
        }
    */

    /**
     * Return the current state of the permissions needed.
     */
    private boolean checkPermissions() {
        int permissionState = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
        return permissionState == PackageManager.PERMISSION_GRANTED;
    }

    private void requestPermissions() {
        boolean shouldProvideRationale = ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION);

        // Provide an additional rationale to the user. This would happen if the user denied the
        // request previously, but didn't check the "Don't ask again" checkbox.
        if (shouldProvideRationale) {
            Log.i(TAG, "Displaying permission rationale to provide additional context.");
            Snackbar.make(findViewById(R.id.main_activity_view), "Permission Rationale", Snackbar.LENGTH_LONG)
                    .setAction("Ok", new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            // Request permission
                            ActivityCompat.requestPermissions(FitnessActivity.this,
                                    new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                                    REQUEST_PERMISSIONS_REQUEST_CODE);
                        }
                    }).show();
        } else {
            Log.i(TAG, "Requesting permission");
            // Request permission. It's possible this can be auto answered if device policy
            // sets the permission in a given state or the user denied the permission
            // previously and checked "Never ask again".
            ActivityCompat.requestPermissions(FitnessActivity.this,
                    new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, REQUEST_PERMISSIONS_REQUEST_CODE);
        }
    }

    /**
     * Callback received when a permissions request has been completed.
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
            @NonNull int[] grantResults) {
        Log.i(TAG, "onRequestPermissionResult");
        if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
            if (grantResults.length <= 0) {
                // If user interaction was interrupted, the permission request is cancelled and you
                // receive empty arrays.
                Log.i(TAG, "User interaction was cancelled.");
            } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission was granted.
                buildFitnessClient();
            } else {
                // Permission denied.

                // In this Activity we've chosen to notify the user that they
                // have rejected a core permission for the app since it makes the Activity useless.
                // We're communicating this message in a Snackbar since this is a sample app, but
                // core permissions would typically be best requested during a welcome-screen flow.

                // Additionally, it is important to remember that a permission might have been
                // rejected without asking the user for permission (device policy or "Never ask
                // again" prompts). Therefore, a user interface affordance is typically implemented
                // when permissions are denied. Otherwise, your app could appear unresponsive to
                // touches or interactions which have required permissions.
                Snackbar.make(findViewById(R.id.main_activity_view), "Permission denied", Snackbar.LENGTH_LONG)
                        .setAction("Settings", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                // Build intent that displays the App settings screen.
                                Intent intent = new Intent();
                                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                Uri uri = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null);
                                intent.setData(uri);
                                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                startActivity(intent);
                            }
                        }).show();
            }
        }
    }
}