Java tutorial
/* * 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(); } } } }