This repo has been migrated to github.com/android/fit. Please check that repo for future updates. Thank you!
googlearchive / android-fit Goto Github PK
View Code? Open in Web Editor NEWMigrated:
Home Page: https://github.com/android/fit
Migrated:
Home Page: https://github.com/android/fit
This repo has been migrated to github.com/android/fit. Please check that repo for future updates. Thank you!
Hi,
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
.
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
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.
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")
}
I'd like to ask you what is the diffrences between Fitness.getConfigClient(context, account).disableFit()
and GoogleSignInClient.revokeAccess
?
Thank you
Missed content ... sorry
When I build & run the sample after accepting permissions and Google Fit I get the error:
Exception while connecting to Google Play services: null
Getting Exception "Google Play services connection failed. Cause: ConnectionResult{statusCode=CANCELED, resolution=null, message=null}" when trying to add a google acount.
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.
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.
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.
"Cannot resolve method setActivity(java.lang.String)"
BasicHistorySession: MainActivity.java: lines 338, 343, 348
Its not even there in the documentation!
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:
๐
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.
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()
}
Fitness.getRecordingClient(context, client!!)
.subscribe(DataType.TYPE_STEP_COUNT_DELTA)
.addOnSuccessListener {
onSuccess.invoke()
}
.addOnFailureListener { e ->
onFail.invoke(e)
}
// 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)
}
I ran the History API demo inserted step data, but the data dit not showed at Google Fit APP, what's
wrong?
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 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?
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
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.
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?
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.
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
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());
}
}
});
I m using GoogleFit Sdk step to step from this project but i m not able to logout session of google account, Please give me suggestion. What should i do ?
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.
Shouldn't BasicHistorySessions manifest include:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Otherwise Request Permissions isn't shown
I'm not able to remove the listener from SensorsApi. After the remove(mListener) method is called, task.getResult() returns false in the OnComplete method.
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
}
}
});
}
When I run app the pop-up select email to authen to Google, I select the email but the app always throw StatusCode = CANCEL. Does the authen funtion out of date ? Do we need to switch to this authen guide: https://developer.android.com/training/wearables/apps/auth-wear.html#configure-google-sign-in
Do we need to include the api key? If so what is the name of it in the meta data tag.
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
Are you creating or thinking about create this project in Kotlin?
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
I want read HealthDataTypes (temperature, blood pressure and glucose). Which Scope I must set when create GoogleApiClient?
.addScope(new Scope(????))
I'm trying to copy the official Google Fit sample from here https://www.youtube.com/watch?v=jwaQaWGLlTo#t=178. I'm having problems with the DataSourceListener
. When I try to add that class in AndroidStudio it doesn't seem to find it, the class doesn't seem to exist...
How to debug in real time sessions/activities (data insertion), it is take hours until the data shows in Google fit app, sometimes it does not show all, even when onSuccess and onComplete called, very hard to test with this delays.
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.
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:
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
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?
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 :
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.
History API return same value with Google Fit App.
As for addition, both approach are returning 3300 datapoint rather than 2433 datapoint.
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());
}
});
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);
}
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
"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
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();
}
}
}
}
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.
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:
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?
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.