Coder Social home page Coder Social logo

android-fit's Introduction

Android Fit Samples

This repo has been migrated to github.com/android/fit. Please check that repo for future updates. Thank you!

android-fit's People

Contributors

codingjeremy avatar joannasmith avatar mgoodridge avatar naokigoogle avatar paulrashidi avatar willum070 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

android-fit's Issues

GoogleSignIn.hasPermissions always return true even if I call disableFit

Hi,

The situation

I'm trying to enable/disable google fit in my app with a Switch View.

When I turn off this switch, I call below code.

Fitness.getConfigClient(context, account).disableFit()
                .addOnSuccessListener {
                    Timber.d("disconnectGoogleFit: onSuccess")
                }
                ...

After onSuccess, I turn on switch to connect google fit and call below.

if (GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount(this), fitnessOptions){
 return
}
GoogleSignIn.requestPermissions(
        this, // your activity
        GOOGLE_FIT_PERMISSIONS_REQUEST_CODE,
        GoogleSignIn.getLastSignedInAccount(this),
        fitnessOptions);

Nothing happens because GoogleSignIn.hasPermissions always return true.

What I want to do

I'd like to check whether Google fit permission is granted or not before calling GoogleSignIn.requestPermissions

Please tell me how to do this.

Thank you


Update

I think I have found a solution that disconnecting app through Google Fit App. After this, GoogleSignIn.hasPermissions return false.
But I am curious how can do this programmatically.

Solved

GoogleSignInClient.revokeAccess works. I don't know the reasons why.

 val signInOptions = GoogleSignInOptions.Builder().addExtension(fitnessOptions).build()
            val client = GoogleSignIn.getClient(context, signInOptions)
            client.revokeAccess()
                .addOnSuccessListener {
                    Timber.d("disconnectGoogleFit: onSuccess")
                }

Question

I'd like to ask you what is the diffrences between Fitness.getConfigClient(context, account).disableFit() and GoogleSignInClient.revokeAccess?

Thank you

Failing to recreate GoogleApiClient after upgrading play services 9.0.2

I made a fork from android-fit google's github project and added a couple of commits.

The problem comes with play-services-fitness version upgrade. It works as expected in 8.4.0 but if you upgrade to 9.0.2 appears the issue of recreating googleApiClient.

I'm trying to solve the case when the googleApiClient has to be recreated because stopAutoManage has been automatically called due to some error (either user canceled the sign-in dialog, or other client was alive but was manually stopAutomanage called). See the gifs.

So to sum up, the question is how to properly recreate the GoogleApiClient with play services 9+?

There's also an issue in android bug tracker.

is there any way to get the actual create time for a session?

looks like the fit system will use the end time as the "timestamp" field which may not be the actual create time of a session. For example,

a running session may happened from 13:00 to 14:00 on a third party app but the actual sync to google fit happens on 18:00 triggered by user manually.

my app just want to retrieve the New Sessions since the last read but if can not get the actual create time in the google fit then there is no way to do this?

any suggestions? Thx.

how to get past 1 month data?

I want to know how to get google fit past 30days data.
I use this way, 'aggregate, DataType.AGGREGATE_STEP_COUNT_DELTA',and 'bucketByTime(1, TimeUnit.DAYS)'
but I can not get whole 30days, only get 15 or 16days.


long aDayMills = 1000 * 60 * 60 * 24;

DataSource ESTIMATED_STEP_DELTAS = new DataSource.Builder()
                    .setDataType(DataType.TYPE_STEP_COUNT_DELTA)
                    .setType(DataSource.TYPE_DERIVED)
                    .setStreamName("estimated_steps")
                    .setAppPackageName("com.google.android.gms")
                    .build();

            for (int i = 1; i < 30; i++) {

                long start = start - (aDayMills * i);
                long end = start - (aDayMills * (i - 1)) - 1; 

                DataReadRequest readRequest = new DataReadRequest.Builder()
                        .aggregate(ESTIMATED_STEP_DELTAS, DataType.AGGREGATE_STEP_COUNT_DELTA)
                        .aggregate(DataType.TYPE_DISTANCE_DELTA, DataType.AGGREGATE_DISTANCE_DELTA)
                        .aggregate(DataType.TYPE_CALORIES_EXPENDED, DataType.AGGREGATE_CALORIES_EXPENDED)
                        .aggregate(DataType.TYPE_ACTIVITY_SEGMENT, DataType.AGGREGATE_ACTIVITY_SUMMARY)
                        .bucketByTime(1, TimeUnit.DAYS)
                        .setTimeRange(start, end, TimeUnit.MILLISECONDS)
                        .build();

                Fitness.HistoryApi.readData(googleApiClient, readRequest).setResultCallback(new com.google.android.gms.common.api.ResultCallback<DataReadResult>() {
                    @Override
                    public void onResult(@NonNull DataReadResult dataReadResult) {
                        com.google.android.gms.common.api.Status status = dataReadResult.getStatus();
                        if (status.isSuccess()) {
                            printData(dataReadResult);
                        } else {
                            Log.d(TAG, "statusCode:" + status.getStatusCode() + ",message:" + status.getStatusMessage());
                        }
                    }
                });
            }

I cannot get correct data if get whole 30days data by one request.

please tell me how to get whole past 30days fit data.
thanks.

Non existent function -_-

"Cannot resolve method setActivity(java.lang.String)"

BasicHistorySession: MainActivity.java: lines 338, 343, 348

Its not even there in the documentation!

OnDataPointListener Stops getting updates randomly?

All,

My team noticed this problem in our application which uses your Sensors API to show users their distance traveled. Every time we start a walk, eventually, the OnDataPointListener just stops giving updates that there's a new DataPoint available(even though user is moving). I've seen it take anywhere from 5 mins to 1.5 hours to stop working. We have log statements tracking when theres an update, when the client gets disconnected(if it ever does), when a client gets built, etc. There is no callback when this happens. I forked your sample app to try and see if this was an API issue, and it looks like it is.
https://github.com/RyanNewsom/android-fit/tree/master/BasicSensorsApi

Steps to reproduce:

  1. Download my sample app, launch, press start.
  2. Confirm updates are coming in
  3. Background the app, hit the hold button to turn off the screen
  4. Put phone in pocket/on a table for 10-30 mins
  5. Foreground app and walk around of shake the phone to see if you are getting updates
  6. repeat 3-5 until you see you are not getting updates

๐Ÿ™

Always returns empty dataset

I'm developing a step counter with Google Fit.
I tried to implement as it is defined in Google Fit docs. But the problem is that when I query step count it always returns empty dataset but when I query with readDailyTotal function it returns a dataset.
I am not able to find what is the cause.

  1. I get the required permission for required step count permission
val fitnessOptions = FitnessOptions.builder()
.addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)  
.addDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE, FitnessOptions.ACCESS_READ)  
.addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)  
.build()

if (! GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount(activity),  
fitnessOptions)) {
    GoogleSignIn.requestPermissions(
        activity, // your activity
        REQUEST_CODE_GOOGLE_FIT_PERMISSIONS,
        GoogleSignIn.getLastSignedInAccount(activity),
        fitnessOptions
    )
} else {
    onSuccess.invoke()
}
  1. I subscribe to the application for recording step counts.
Fitness.getRecordingClient(context, client!!)
.subscribe(DataType.TYPE_STEP_COUNT_DELTA)
.addOnSuccessListener {
    onSuccess.invoke()
}
.addOnFailureListener { e ->
    onFail.invoke(e)
}
  1. I query 1 week period with history API but it always returns an empty dataset.
// Setting a start and end date using a range of 1 week before this moment.  
val cal = Calendar.getInstance()  
val now = Date()  
cal.time = now  
val endTime = cal.timeInMillis  
cal.add(Calendar.WEEK_OF_YEAR, -1)  
val startTime = cal.timeInMillis  

val dateFormat = DateFormat.getDateInstance()
Log.i(TAG, "Range Start: " + dateFormat.format(startTime))
Log.i(TAG, "Range End: " + dateFormat.format(endTime))

val readRequest = DataReadRequest.Builder()
// The data request can specify multiple data types to return, effectively
// combining multiple data queries into one call.
// In this example, it's very unlikely that the request is for several hundred
// datapoints each consisting of a few steps and a timestamp.  The more likely
// scenario is wanting to see how many steps were walked per day, for 7 days.
.aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
// Analogous to a "Group By" in SQL, defines how data should be aggregated.
// bucketByTime allows for a time span, whereas bucketBySession would allow
// bucketing by "sessions", which would need to be defined in code.
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.enableServerQueries()
.build()
Fitness.getHistoryClient(context, client)
    .readData(readRequest)
    .addOnSuccessListener { dataReadResponse ->
        dumpDataSets(dataReadResponse.dataSets)
        onSuccess.invoke(dataReadResponse)
    }
    .addOnFailureListener { e ->
        onFail.invoke(e)
    }
    .addOnCompleteListener { task ->
        dumpDataSets(task.result!!.dataSets)
        onComplete.invoke(task)
    }

Is there a limit on SessionReadRequest with dataSets?

When I try to use SessionReadRequest to parse data from 1 month it does not return anything. In the beginning this worked, but as newer sessions now include TYPE_HEART_RATE_BPM dataType it doesn't work anymore. When I don't read this dataType or lower the time to only 3 days back in time it works.. Could anyone help me with this issue. Is there some sort on limit on a SessionReadRequest? Below is my code for reading the sessions. Once a session is read is goes to the populateList where they are added to a list and when completed notify a RecyclerView.

private SessionReadRequest readFitnessSession() {
        // [START build_read_session_request]
        // Set a start and end time for query, using a start time of 1 month before this moment.
        Calendar cal = Calendar.getInstance();
        Date now = new Date();
        cal.setTime(now);
        long endTime = cal.getTimeInMillis();
        cal.add(Calendar.MONTH, -1);
        long startTime = cal.getTimeInMillis();

        // Build a session read request
        SessionReadRequest readRequest = new SessionReadRequest.Builder()
                .setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS)
                .read(DataType.TYPE_HEART_RATE_BPM)
                .read(DataType.AGGREGATE_DISTANCE_DELTA)
                .readSessionsFromAllApps()
                //.enableServerQueries()
                .build();
        // [END build_read_session_request]

        return readRequest;
    }
private Task<SessionReadResponse> readSession() {
        // Begin by creating the query.
        SessionReadRequest readRequest = readFitnessSession();

        // [START read_session]
        // Invoke the Sessions API to fetch the session with the query and wait for the result
        // of the read request. Note: Fitness.SessionsApi.readSession() requires the
        // ACCESS_FINE_LOCATION permission.
        return Fitness.getSessionsClient(this, GoogleSignIn.getLastSignedInAccount(this))
                .readSession(readRequest)
                .addOnSuccessListener(new OnSuccessListener<SessionReadResponse>() {
                    @Override
                    public void onSuccess(SessionReadResponse sessionReadResponse) {
                        // Get a list of the sessions that match the criteria to check the result.
                        Log.i(TAG, "Session read was successful");
                        populateList(sessionReadResponse);
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.i(TAG, "Failed to read session");
                    }
                });
        // [END read_session]
    }

Error

Error when trying new versions of Google Fit samples,

E/AndroidRuntime: FATAL EXCEPTION: GoogleApiHandler Process: com.google.android.gms.fit.samples.basicrecordingapi, PID: 22949 java.lang.NullPointerException: Attempt to invoke virtual method 'android.accounts.Account com.google.android.gms.auth.api.signin.GoogleSignInAccount.getAccount()' on a null object reference at com.google.android.gms.common.api.GoogleApi.zzagd(Unknown Source) at com.google.android.gms.common.api.GoogleApi.zza(Unknown Source) at com.google.android.gms.common.api.internal.zzbr.<init>(Unknown Source) at com.google.android.gms.common.api.internal.zzbp.zzb(Unknown Source) at com.google.android.gms.common.api.internal.zzbp.handleMessage(Unknown Source) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:158) at android.os.HandlerThread.run(HandlerThread.java:61)

have changed the methods and I have noticed that since then my application using the old methods does not record data for DataType TYPE_ACTIVITY_SEGMENT, TYPE_STEP_COUNT_DELTA and sometimes TYPE_HEART_RATE_BPM. What is the solution?

BasicHistoryApi

Hi,
I'm trying to connecto to google fit using BasicHistoryApi Sample app, but im getting error:

Connection failed. Cause: ConnectionResult{statusCode=SIGN_IN_REQUIRED

I've added SHA1 from my debug.keystore using
-exportcert -alias androiddebugkey -keystore debug.keystore -list -v
I've added it to my fingerprint list in google developer console.
I've enabled Fitness api.

After launching app there is a modal asking for connecting to account, i've selected it.
And still getting this error.

I hope i'm just missing something, and it's not an issue indeed,
will be grateful for any tip

Data differs from the actual Google Fit App

I am building a fitness application where I pull certain data (Steps and Calories) from google fit. I am fetching a week data. The output of the google fit api doesn't match with the google fit data. The output is so random and doesn't have a definite pattern.

Steps From Google Fit API:
Code Used:
private DataReadRequest queryFitnessData()
{
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
cal.add(Calendar.WEEK_OF_YEAR, -1);
long startTime = cal.getTimeInMillis();
java.text.DateFormat dateFormat = getDateInstance();
Timber.e("Range Start: " + dateFormat.format(startTime));
Timber.e("Range End: " + dateFormat.format(endTime));
return new DataReadRequest.Builder()
.aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build();
}

public Observable getStepsCount(GoogleApiClient googleApiClient) {
return Observable.create(subscriber -> {
DataReadResult result =
Fitness.HistoryApi.readData(googleApiClient, queryFitnessData()).await(1, TimeUnit.MINUTES);
if (result.getStatus().isSuccess()) {
subscriber.onNext(result);
} else {
subscriber.onError(new Exception("Exception"));
}
});
}

Output
Start Date: 17th August 2017 End Date: 24th August 2017

17-18 -> 4080
18-19 -> 3837
19-19 -> 7
20-21 -> 2212
21-22 -> 4665
23-23 -> 2949
23-24 -> 6131

Any help would be greatly appreciated. If required, apk can also be shared.

Do we need Google Fit App for Google Fit API?

I made small test app which shows daily steps using Google Fit API. During testing, I was not getting any steps count. But later I realised that my Samsung device doesn't come's with Google Fit app so I downloaded it and after feeding some data then I tested my app again and Now I can see my steps count on my test app.

So Does this means that in order to use Google Fit API all my app users must have installed Google Fit App?

Google Account Sign_IN_FAILED

I used these sample and found that I couldn't login.

Error Message :
Connection failed. Cause: ConnectionResult{statusCode=SIGN_IN_FAILED, resolution=null}

I don't know how to fix it.

How to read steps session wise.

I am in need to show steps time line wise like below.

Time 10 am - 56 steps
Time 11 am - 156 steps
Time 4.30 pm - 236 steps

I don't want to aggregate by hour or anything , i just want the actual data that is currently google fit app is showing in timeline using steps filter.

However i am able to retrieve steps using bucketBySession that entered manually into google fit app but not able to retrieve those steps history which is generated automatically.

Please let me know how to overcome this.

Below is my sample code.

       // Build a session read request
       SessionReadRequest readRequest = new SessionReadRequest.Builder()
               .setTimeInterval(times[0], times[1], TimeUnit.MILLISECONDS)
               .readSessionsFromAllApps()
               .read(DataType.TYPE_STEP_COUNT_DELTA)
               .enableServerQueries()
               .build();

       Fitness.getSessionsClient(mContext, GoogleSignIn.getLastSignedInAccount(mContext))
               .readSession(readRequest)
               .addOnSuccessListener(new OnSuccessListener<SessionReadResponse>() {
                   @Override
                   public void onSuccess(SessionReadResponse sessionReadResponse) {
                       // Get a list of the sessions that match the criteria to check the result.
                       List<Session> sessions = sessionReadResponse.getSessions();
                       Log.i(TAG, "Session read was successful. Number of returned sessions is: "
                               + sessions.size());

                       for (Session session : sessions) {
                           // Process the session
                           dumpSession(session);

                           // Process the data sets for this session
                           List<DataSet> dataSets = sessionReadResponse.getDataSet(session);
                           for (DataSet dataSet : dataSets) {
                               dumpDataSet(dataSet);
                           }
                       }
                   }
               })
               .addOnFailureListener(new OnFailureListener() {
                   @Override
                   public void onFailure(@NonNull Exception e) {
                       Log.i(TAG, "Failed to read session");
                   }
               });

    final DataReadRequest req = new DataReadRequest.Builder()
               .aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
               .aggregate(DataType.TYPE_ACTIVITY_SEGMENT, DataType.AGGREGATE_ACTIVITY_SUMMARY)
               .enableServerQueries()
               .bucketBySession(1, TimeUnit.MINUTES)
               .setTimeRange(times[0], times[1], TimeUnit.MILLISECONDS)
               .build();

   Fitness.getHistoryClient(mContext, GoogleSignIn.getLastSignedInAccount(mContext))
               .readData(req)
               .addOnSuccessListener(
                       dataReadResponse -> readData(dataReadResponse, MESSAGE_HEALTH_DATA_LIST_KEY))
               .addOnFailureListener(
                       e -> {
                       });

I am trying with the both client , session as well as history but didn't get any suceess.
thanks,
Krunal

Google Fit API: ApiException 17 (Fitness.CLIENT is not available on this device)

I configured Google fit api and followed "Getting Started" section of google docs. But when I trying to read "Steps" data I face "Google Fit API: ApiException 17 (Fitness.CLIENT is not available on this device)" exception in Task object callback from getRecordingClient

        Fitness.getRecordingClient(context, GoogleSignIn.getLastSignedInAccount(context))
                .subscribe(DataType.TYPE_STEP_COUNT_CUMULATIVE)
                .addOnCompleteListener(
                        new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                if (task.isSuccessful()) {
                                    Log.i(LOG_TAG, "Successfully subscribed!");
                                } else {
                                    Log.w(LOG_TAG, "There was a problem subscribing.", task.getException());
                                }
                            }
                        });

How to get heart points?

Here is my code :

Fitness.getHistoryClient(this, GoogleSignIn.getLastSignedInAccount(this))
.readDailyTotalFromLocalDevice(DataType.TYPE_HEART_POINTS)
.addOnSuccessListener(new OnSuccessListener() {
@OverRide
public void onSuccess(DataSet dataSet) {
showDataSet(dataSet);
}
})
.addOnFailureListener(new OnFailureListener() {
@OverRide
public void onFailure(@nonnull Exception e) {
Log.d(LOG_TAG, "onFailure: " + e.getMessage());
}
});

FitnessOptions fitnessOptions = FitnessOptions.builder()
.addDataType(DataType.TYPE_HEART_POINTS, FitnessOptions.ACCESS_READ)
.addDataType(DataType.AGGREGATE_HEART_POINTS, FitnessOptions.ACCESS_READ)
.addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
.addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
.addDataType(DataType.TYPE_DISTANCE_DELTA, FitnessOptions.ACCESS_READ)
.addDataType(DataType.AGGREGATE_DISTANCE_DELTA, FitnessOptions.ACCESS_READ)
.addDataType(DataType.TYPE_CALORIES_EXPENDED, FitnessOptions.ACCESS_READ)
.build();

    if (!GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount(this), fitnessOptions)) {
        GoogleSignIn.requestPermissions(
                this, // your activity
                GOOGLE_FIT_PERMISSIONS_REQUEST_CODE,
                GoogleSignIn.getLastSignedInAccount(this),
                fitnessOptions);
    } else {
        accessGoogleFit();
    }

I am getting this error (5000: Application needs OAuth consent from the user) while I have given permission as mentioned above.

Not able to read custom data saved of google fit server

I have successfully uploaded my custom data to google fit server. using following code.

com.google.android.gms.common.api.Status insertStatus =
Fitness.HistoryApi.insertData(mClient, dataSet)
.await(1, TimeUnit.MINUTES);
if (!insertStatus.isSuccess()) {
Log.i(TAG, "There was a problem inserting the dataset.");
return null;
}

    Log.i(TAG, "Data insert was successful!");

I found that also I can read custom data value within my app, but I am not getting it. Following is the code to retrieve it.

final PendingResult pendingResult = Fitness.ConfigApi.readDataType(
mClient, "com.fitnessapi.custom_data_type");

            pendingResult.setResultCallback(
                    new ResultCallback<DataTypeResult>() {
                        @Override
                        public void onResult(DataTypeResult dataTypeRes) {

                            DataSet dataSet = DataSet.create(dataSource);

                            List<DataPoint> points= dataSet.getDataPoints();

                            for(int i=0; i<points.size();i++)
                            {
                               //Never getting values
                            }
                        }
                    });
        }

Error:Could not find com.googlecode.json-simple:json-simple:1.1.

I get the following error while trying to open the BasicSensorsApi project:

Error:Could not find com.googlecode.json-simple:json-simple:1.1.
Searched in the following locations:
file:/Applications/Android Studio 3.0 Preview.app/Contents/gradle/m2repository/com/googlecode/json-simple/json-simple/1.1/json-simple-1.1.pom
file:/Applications/Android Studio 3.0 Preview.app/Contents/gradle/m2repository/com/googlecode/json-simple/json-simple/1.1/json-simple-1.1.jar
https://dl.google.com/dl/android/maven2/com/googlecode/json-simple/json-simple/1.1/json-simple-1.1.pom
https://dl.google.com/dl/android/maven2/com/googlecode/json-simple/json-simple/1.1/json-simple-1.1.jar
Required by:
project : > com.android.tools.build:gradle:3.0.0 > com.android.tools.build:gradle-core:3.0.0 > com.android.tools.build:builder:3.0.0

Basic Sensors Api

In the sample app if you try to replace TYPE_LOCATION_SAMPLE with TYPE_DISTANCE_DELTA or anything else. The field and its respective values are not getting fetched

Signed APK doesn't show subsription page.

Hi,
I have tried this google fitness API as a sample one. When i am getting apk in debug format, it run perfectly .When i run this , initially it subscribe by using gmail account and provides step count value as i expect. But when i try with signed APK, its doesn't work. It doesn't show the subscription dialog and also the count doesn't show without subscription. Please give solution regarding that. Thanks.

Sample build fails due to missing dependency

Unable to build the basic sensors sample due to a missing dependency. I'm new to gradle so I don't know how to fix the build issue.

Pre-requisites says:

  • Android API Level >v9
  • Android Build Tools >v19
  • Android Support Repository

My environment:

Android SDK Build-tools: 23.0.5
Android 5.0 (API 21)
Android Support Repository 7
Android Support Library 21
Google Play services 21

Build:

$ gradlew build
Relying on packaging to define the extension of the main artifact has been deprecated and is scheduled to be removed in Gradle 2.0

FAILURE: Build failed with an exception.

  • What went wrong:
    A problem occurred configuring project ':app'.

    Could not resolve all dependencies for configuration ':app:_debugCompile'.
    Could not find any version that matches com.google.android.gms:play-services:6.1.+.
    Required by:
    BasicSensorsApi:app:unspecified

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 4.582 secs

Error: No permission to read data for this private data source.

I use Google Fit REST API for over 2 years and everything was fine already. However since 20th November I am occuring the only reply on route:

/me/dataSources/derived:com.google.location.sample:com.google.android.gms:merge_high_fidelity/datasets/

( 'domain' => 'global', 
'reason' => 'forbidden', 
'message' => 'No permission to read data for this private data source.', )

I had not changed anything in my code, did Google change something?

Values that returned from History API is not the same with Google Fit App

What happened

Step count value that I've been received from History API was different with step count values that has been displayed in Fit App. Even problem solving for different values between Fit History Api and Google Fit App has been mentioned here, sometimes this problem still occurred in certain device.

In my case, I was using :

  • Phone HTC One_E8 dual sim
  • Android version 6.0.1
  • Google Play services 14.3.66
Fit API Prober Fit App

As you can see that in Fit API prober, I got 3300 datapoint for today step count, meanwhile in Fit App, 2433 datapoint has been displayed. The margin is quite huge in this case.

What was expected

History API return same value with Google Fit App.

Code Snippets

As for addition, both approach are returning 3300 datapoint rather than 2433 datapoint.

History API today step count
        Fitness.getHistoryClient(mContext, GoogleSignIn.getLastSignedInAccount(mContext))
            .readDailyTotal(DataType.TYPE_STEP_COUNT_DELTA)
            .addOnSuccessListener(new OnSuccessListener<DataSet>() {
                @Override
                public void onSuccess(DataSet dataSet) {
                    int totalStepCount = extractHistoryFromDataSet(dataSet);
                    callback.onResult(totalStepCount);
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    callback.onError(e.getMessage());
                }
            });
History API through step count aggregation
DataSource getFitStepCountDataSource() {
        return new DataSource.Builder()
                .setDataType(DataType.TYPE_STEP_COUNT_DELTA)
                .setType(DataSource.TYPE_DERIVED)
                .setStreamName("estimated_steps")
                .setAppPackageName("com.google.android.gms")
                .build();
}

Task<DataReadResponse> readHistory(long startTime, long endTime) {
        DataReadRequest request = new DataReadRequest.Builder()
            .aggregate(getFitStepCountDataSource(), DataType.AGGREGATE_STEP_COUNT_DELTA)
            .bucketByTime(1, TimeUnit.DAYS)
            .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
            .enableServerQueries()
            .build();
        return Fitness.getHistoryClient(mContext, GoogleSignIn.getLastSignedInAccount(mContext))
            .readData(request);
}

couldnt get account info

java.lang.NullPointerException: Attempt to invoke virtual method 'android.accounts.Account com.google.android.gms.auth.api.signin.GoogleSignInAccount.getAccount()' on a null object reference

error caught in step counter

Missing sample of BroadcastReceiver for Session Start/End

"Google Fit broadcasts intents when any app starts or stops recording a session on behalf of the user. Fitness apps can register a listener to receive these intents."

Can we please have a sample of that? I am trying to implement one myself but not being able to receive intents right now and having a sample would be very helpful.

Kind regards,
Rubin

Always my history api returns empty Buckets

public class MainActivity extends AppCompatActivity {

public static final String TAG = "StepCounter";
private static final int REQUEST_OAUTH_REQUEST_CODE = 0x1001;
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
private GoogleApiClient mClient = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_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();
    if (!checkPermissions()) {
        requestPermissions();
    } else {
        callGoogleClient();
    }

}

private void callGoogleClient() {
    FitnessOptions fitnessOptions =
            FitnessOptions.builder()
                    .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
                    .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_WRITE)
                    .addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
                    .addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_WRITE)
                    .addDataType(DataType.TYPE_ACTIVITY_SEGMENT, FitnessOptions.ACCESS_READ)
                    .addDataType(DataType.TYPE_ACTIVITY_SEGMENT, FitnessOptions.ACCESS_WRITE)
                    .build();
    if (!GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount(this), fitnessOptions)) {
        GoogleSignIn.requestPermissions(
                this,
                REQUEST_OAUTH_REQUEST_CODE,
                GoogleSignIn.getLastSignedInAccount(this),
                fitnessOptions);
    } else {
        getFitData();
    }

}

private boolean checkPermissions() {
    int permissionState = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION);
    int permissionState1 = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.BODY_SENSORS);
    return permissionState == PackageManager.PERMISSION_GRANTED && permissionState1 == PackageManager.PERMISSION_GRANTED;
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == Activity.RESULT_OK) {
        if (requestCode == REQUEST_OAUTH_REQUEST_CODE) {
            getFitData();
          }
    }
}

private void getFitData() {
    if (mClient == null && checkPermissions()) {
        mClient = new GoogleApiClient.Builder(this)
                .addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
                .addScope(new Scope(Scopes.FITNESS_BODY_READ))
                .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ))
                .addApi(Fitness.HISTORY_API)
                .addConnectionCallbacks(
                        new GoogleApiClient.ConnectionCallbacks() {
                            @Override
                            public void onConnected(Bundle bundle) {
                                android.util.Log.i(TAG, "Connected!!!");
                                subscribeToFetching();
                            }

                            @Override
                            public void onConnectionSuspended(int i) {
                                if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
                                } else if (i
                                        == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
                                }
                            }
                        }
                )
                .enableAutoManage(this, 4, new GoogleApiClient.OnConnectionFailedListener() {
                    @Override
                    public void onConnectionFailed(ConnectionResult result) {
                        android.util.Log.i("onConnectionFailed", result.getErrorMessage());
                    }
                })
                .build();
    }
}

private void
subscribeToFetching() {
    new BackgroundFetching().execute();
     }

private void getData() {
    try {
        Calendar cal = Calendar.getInstance();
        Date now = new Date();
        cal.setTime(now);
        long endTime = cal.getTimeInMillis();
        cal.add(Calendar.HOUR, -cal.getInstance().get(Calendar.HOUR_OF_DAY));
        cal.add(Calendar.MINUTE, -cal.getInstance().get(Calendar.MINUTE));
        cal.add(Calendar.SECOND, -cal.getInstance().get(Calendar.SECOND));
        long startTime = cal.getTimeInMillis();
        //long startTime = Long.parseLong("1535602500000");


        android.util.Log.i(TAG, "Start Time: " + android.text.format.DateFormat.format("yyyy-MM-dd hh:mm:ss a", startTime));
        android.util.Log.i(TAG, "End Time: " + android.text.format.DateFormat.format("yyyy-MM-dd hh:mm:ss a", endTime));


        DataReadRequest readRequest = new DataReadRequest.Builder()
                .aggregate(DataType.AGGREGATE_STEP_COUNT_DELTA, DataType.TYPE_STEP_COUNT_DELTA)
                // .aggregate(DataType.TYPE_HEART_RATE_BPM, DataType.AGGREGATE_HEART_RATE_SUMMARY)
                /// .aggregate(DataType.TYPE_CALORIES_EXPENDED, DataType.AGGREGATE_CALORIES_EXPENDED)
                .enableServerQueries()
                .bucketByTime(24, TimeUnit.HOURS)
                .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
                .build();
        PendingResult<DataReadResult> result = Fitness.HistoryApi.readData(mClient, readRequest);

        result.setResultCallback(new ResultCallback<DataReadResult>() {
            @Override
            public void onResult(@NonNull DataReadResult dataReadResult) {
                int totalSteps = 0;
                if (dataReadResult.getBuckets().size() > 0) {
                    for (Bucket bucket : dataReadResult.getBuckets()) {
                        for (DataSet set : bucket.getDataSets()) {
                            for (DataPoint dp : set.getDataPoints()) {
                                for (Field field : dp.getDataType().getFields()) {
                                    int steps = dp.getValue(field).asInt();
                                    totalSteps += steps;
                                    Toast.makeText(MainActivity.this, totalSteps, Toast.LENGTH_LONG).show();

                                }

                            }
                        }

                    }
                }
            }
        });

    } catch (Exception e) {
        android.util.Log.i(TAG, "Error msg: " + e.getMessage());
    }
}

private class BackgroundFetching extends AsyncTask<Void, Void, Void> {

    protected Void doInBackground(Void... params) {
        getData();
        return null;
    }
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the main; 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_read_data) {
        readData();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * Initializes 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 error adds logic without benefit.
    // noinspection AndroidLintDeprecation
    logView.setTextAppearance(R.style.Log);

    logView.setBackgroundColor(Color.WHITE);
    msgFilter.setNext(logView);
    Log.i(TAG, "Ready");
}

private void requestPermissions() {
    boolean shouldProvideRationale =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);
    if (shouldProvideRationale) {
        Snackbar.make(
                findViewById(R.id.main_activity_view),
                "RequestPremission",
                Snackbar.LENGTH_INDEFINITE)
                .setAction(R.string.intro_text, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Request permission
                        ActivityCompat.requestPermissions(MainActivity.this,
                                new String[]{Manifest.permission.BODY_SENSORS},
                                REQUEST_PERMISSIONS_REQUEST_CODE);
                    }
                })
                .show();
    } else {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BODY_SENSORS},
                REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    android.util.Log.i(TAG, "onRequestPermissionResult");
    if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
        if (grantResults.length <= 0) {
            android.util.Log.i(TAG, "User interaction was cancelled.");
        } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            callGoogleClient();
        } else {
            Snackbar.make(
                    findViewById(R.id.main_activity_view),
                    "Premission not Granted",
                    Snackbar.LENGTH_INDEFINITE)
                    .setAction(R.string.intro_text, 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();
        }
    }
}

}

sphal namespace is not configured for this process.

I am trying to run the BasicSensorsApi code but getting this error after choosing the gmail account.
I am using an Android Oreo One PLus5.

This is the error I am getting.

04-01 01:30:26.680 26997-26997/com.google.android.gms.fit.samples.basicsensorsapi D/AppTracker: App Event: stop
04-01 01:30:26.717 26997-27076/com.google.android.gms.fit.samples.basicsensorsapi I/Adreno: QUALCOMM build : d52c199, I26dffed9a4
Build Date : 01/09/18
OpenGL ES Shader Compiler Version: EV031.22.00.01
Local Branch :
Remote Branch : refs/tags/AU_LINUX_ANDROID_LA.UM.6.4.R1.08.00.00.309.052
Remote Branch : NONE
Reconstruct Branch : NOTHING
04-01 01:30:26.717 26997-27076/com.google.android.gms.fit.samples.basicsensorsapi I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8998.so from the current namespace instead.

GoogleSignIn.getLastSignedInAccount for google fit api ALWAYS prompt account selection

I have an app which uses Google Fit. The integration code has been copied from google documentation:
if (!GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount(this), fitnessOptions)) { GoogleSignIn.requestPermissions( this, // your activity GOOGLE_FIT_PERMISSIONS_REQUEST_CODE, GoogleSignIn.getLastSignedInAccount(this), fitnessOptions); } else { accessGoogleFit(); }
In the debug mode, everything works fine, but when my app downloaded from Google Play, it ALWAYS display a prompt for selecting the google account to use:
image
The problem appears only when app downloaded from google play. When app installed with adb, everything works fine.

It seems like, Google Play Services does not cache last selected account.

Please help me, where is the issue here?

Calories Expended from Sensors API No DataSources available

I am working on an application that we are porting over to use your API. I am having no troubles getting DISTANCE_DELTA to come though and give me 2 DataSource's. But when I try to get calories expended I am getting back 0 DataSource's.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.