I am trying to use google fit api in my android app. I followed this guide and created SHA-1 certificate using keytool.exe in my jdk 1.8 bin folder. I have now created Oauth Client ID.
In my app, I get RESULT_CANCELED here:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if( requestCode == REQUEST_OAUTH ) {
authInProgress = false;
if( resultCode == RESULT_OK ) {
if( !mClient.isConnecting() && !mClient.isConnected() ) {
mClient.connect();
}
} else if( resultCode == RESULT_CANCELED ) {/// HERE
Toast.makeText(MainActivity.this,"RESULT_CANCELED",Toast.LENGTH_SHORT).show();
Log.e("GoogleFit", "RESULT_CANCELED");
Log.e("GoogleFit", data.getExtras().toString());
}
}else if(requestCode == CALL_END){
if (resultCode == Activity.RESULT_OK){
//pass
}else{
}
} else {
Log.e("GoogleFit", "requestCode NOT request_oauth");
}
}
Trying to figure out the problem from last two days. I have added correct play services library in android studio as: compile 'com.google.android.gms:play-services-fitness:8.4.0'
Building Client:
private void buildFitnessClient() {
if (mClient == null && checkPermissions()) {
Log.i(TAG, "Building Fitness Client");
mClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.SENSORS_API)
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mClient.connect();
}
}
Callbacks:
/**
* GOOGLE FIT METHODS
*/
@Override
public void onConnected(@Nullable Bundle bundle) {
DataSourcesRequest dataSourceRequest = new DataSourcesRequest.Builder()
.setDataTypes( DataType.TYPE_STEP_COUNT_CUMULATIVE )
.setDataSourceTypes( DataSource.TYPE_RAW )
.build();
ResultCallback<DataSourcesResult> dataSourcesResultCallback = new ResultCallback<DataSourcesResult>() {
@Override
public void onResult(DataSourcesResult dataSourcesResult) {
for( DataSource dataSource : dataSourcesResult.getDataSources() ) {
if( DataType.TYPE_STEP_COUNT_CUMULATIVE.equals( dataSource.getDataType() ) ) {
registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_CUMULATIVE);
}
}
}
};
Fitness.SensorsApi.findDataSources(mClient, dataSourceRequest)
.setResultCallback(dataSourcesResultCallback);
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
if( !authInProgress ) {
try {
authInProgress = true;
connectionResult.startResolutionForResult( MainActivity.this, REQUEST_OAUTH );
} catch(IntentSender.SendIntentException e ) {
}
} else {
Log.e( "GoogleFit", "authInProgress" );
}
}
@Override
public void onDataPoint(DataPoint dataPoint) {
for( final Field field : dataPoint.getDataType().getFields() ) {
final Value value = dataPoint.getValue( field );
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "Field: " + field.getName() + " Value: " + value, Toast.LENGTH_SHORT).show();
HealthRecordFragment.mStepsWalking.setText(value.toString());
}
});
}
}
In Gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.xxxx.xxxx"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
signingConfigs {
release {
storeFile file("C:\\Users\\xxxxx\\AndroidStudioProjects\\HBEAT2\\app\\hbeat_android")
storePassword "password"
keyAlias "hbeat_android"
keyPassword "password"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.android.gms:play-services-fitness:8.4.0'
compile 'com.android.support:appcompat-v7:23.1.1'
compile "com.android.support:design:23.2.1"
compile 'com.github.rahatarmanahmed:circularprogressview:2.4.0'
compile 'de.timroes.android:EnhancedListView:0.3.0'
}
Note: Use of Google's implementation of OAuth 2.0 is governed by the OAuth 2.0 Policies. Google APIs use the OAuth 2.0 protocol for authentication and authorization. Google supports common OAuth 2.0 scenarios such as those for web server, client-side, installed, and limited-input device applications.
Obtain OAuth 2.0 credentials from the Google API Console. Visit the Google API Console to obtain OAuth 2.0 credentials such as a client ID and client secret that are known to both Google and your application. The set of values varies based on what type of application you are building.
If your app requests sensitive scopes, and doesn't meet any of the criteria for an exception (see below), you will need to verify that your app follows the API Services User Data Policy. For a complete list of Google APIs, see OAuth 2.0 Scopes for Google APIs.
Applications on limited-input devices. The Google OAuth 2.0 endpoint supports applications that run on limited-input devices such as game consoles, video cameras, and printers. The authorization sequence begins with the application making a web service request to a Google URL for an authorization code.
I've encountered this problem just now. Took me a few hours to figure out, so i would like to point out for those who make the same mistake.
My Google API client cannot connect only on Production, everything works fine on Development environment.
This is because my app was set up to use "App Signing". With this, if you created the Oauth Client ID using the Production Keystore's SHA1 (or Upload Certificate's SHA1 in the picture), it will not be used, because google will remove this certificate and change to the "App Signing" certificate
So what we need to do to fix the problem is: Simply create a new OAuth Client ID with this new SHA1 like so:
The issue is quite easy to encounter because most of the tutorials will tell you to find your Production SHA1 and use it in the API console. But except for if you use "App signing" then it won't work anymore.
One reason to get RESULT_CANCELED
is if your package name is diferent than the one you define in your app.
Double check that you are not setting another applicationId
in your build.gradle that could be different than package
defined in your manifest.
If the above solutions doesn't help you, then you should definitely consider this solution once. I literally struggled a lot to figure this out. So I think, my findings will help others to avoid same struggle and frustration.
I've followed the google guidelines to set up the GFit authentication. But upon finishing it, I noticed that when my app ask for user's permission, it pops up the authentication screen. But when the user selects one account, it just returns RESULT_CANCELED
in onActivityResult()
instead of RESULT_OK
. The reason behind that was certificate mismatch. I used my project's keystore file to generate the SHA-1
fingerprint which is required for OAuth token generation. But the build that I was deploying was a debug
one. When I tried with the release
build, it worked perfectly. The reason behind that was, Android Studio by default used a debug.keystore
file to sign the debug
builds which is different from the project's keystore file. That's why it didn't work in the debug mode. When I changed the debug
configuration for my project to use my project's keystore file, it worked like a charm. So, I recommend to check this usecase first. Most of the cases, this is the actual issue. You can find another StackOverflow question here which is addresses this issue.
To know more about how to change/modify the signing configurations for your builds, please refer to this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With