Background:
I need to authenticate on my server back-end so I know the client is genuine. In my Android game I connect to Games.API via GoogleApiClient.
I only want to have to sign in once, which I want to do via Games.API, as this gives me many advantages (Google Play Games leaderboards, achievements, etc.)
I have been able to get an authorisation token using GoogleAuthUtil.getToken(...) which I can do after I sign into Games.API, which seems to give me a token. Good so far.
But Google says this is not safe and says I should migrate to ID token flow instead. But, as I understand it this approach would require me to use
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
which means instigating an additional sign in to that for Games.API. Furthermore, it is not possible to addApi both Games.API and Auth.GOOGLE_SIGN_IN_API to the same GoogleApiClient !
Ok, so upgrade to the latest google-play-services (at least r29), using which I can use Games.API with Games.getGamesServerAuthCode(...) to obtain an auth token for my server. But this has two problems: (1) it requires Android 6.0 or above which blocks out 80% of the market, and (2) it's deprecated !
Question:
Should I use GoogleAuthUtil.getToken(...) or not, and if not what are my options given that I only want to sign in using Games.API ?
By sign in I mean present the user with log in visuals. I don't mind signing into something else so long as the user does not have to interact with the sign in...
Note:
I originally asked this question when I first started out. The current question hopefully clarifies the situation.
Firstly, I should not use GoogleAuthUtil.getToken(...). It's deprecated; end of.
To achieve what I want I found the following works perfectly... whether it's the best way I have no idea.
First, sign in using Auth.GOOGLE_SIGN_IN:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(
GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestIdToken("YOUR-SERVER-CLIENT-ID")
.build();
mGoogleApiClientForSignIn = new GoogleApiClient.Builder(mActivity, this, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
mGoogleApiClientForSignIn.connect();
On success this will eventually call onConnected(...) from where you can negotiate a second sign in to Games.API. This has to be performed separately on a new GoogleApiClient because you can't mix Games.API and Auth.GOOGLE_SIGN_IN:
mGoogleApiClientForGames = new GoogleApiClient.Builder(mActivity, this, this)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.addApi(Drive.API).addScope(Drive.SCOPE_APPFOLDER)
.build();
mGoogleApiClientForGames.connect();
As per the new Play Games Permissions update for 2016, the GoogleSignIn only appears once per game (even between devices !), after which the user is not presented with any visual log in screens for GoogleSignIn. The only visual login will be the Saved Games snapshot selection screen.
This works with Android 2.3 (use google-play-services r28) and without deprecation warnings. Huzzah !
Related
I'm trying to implement Google Drive to my Android app and I cannot even connect to Api client. And I don't know why:
I have configured project and credentials in developer console for ~/.android/debug.keystore (values seems to be correct)
I have copy-pasted code from Drive for Android Documentation -> In method onConnectionFailed() I'm calling connectionResult.startResolutionForResult() if connectionResult.hasResolution()
In onActivityResult for matching requestCode I'm receiving resultCode == 0 (RESULT_CANCELLED) even when i select my account
Do you have any idea why? I also tried to add:
<meta-data
android:name="com.google.android.apps.drive.APP_ID"
android:value="----"/>
into Manifest which is not mentioned on documentation page but on some SO posts.
Thanks for help
Edit:
I have also tried to use enableAutoManage
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.build();
instead of manualy configuring connection and connectionFailed callbacks:
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
It returns me error code 13 in onConnectionFailed method. Based on documentation it seems, that this returns when:
OnConnectionFailedListener passed to
enableAutoManage(FragmentActivity,
GoogleApiClient.OnConnectionFailedListener) when the user choses not
to complete a provided resolution. For example by canceling a dialog.
But i didn't cancelled it.
I'm testing it on Nexus 5x - Android N
I found where the problem was while reading something about wallet api
I've just needed to create OAuth client ID not API key
Go to Developer Console > Credentials
Click "create credentials" > OAuth client ID > Android
Fill the details
Create
Open OAuth consent screen (on Credentials page)
Fill email and product name
Save
Now it works!
JUST IN CASE
#VizGhar solution is right if you missed up Client ID creation process. But I get resultCode=0 and everything was fine with my OAuth client ID. And finally I solved it, so I created SHA1 as per documentation, but I run my app in debug mode (Build variant) and always had resultCode=0. Just switched to release mode and problem is gone, now resultCode=-1 as expected.
I am trying to implement App invites in my app. Here's the java code that I am using :
Intent intent = new AppInviteInvitation.IntentBuilder(getString(R.string.invitation_title))
.build();
startActivityForResult(intent, Constants.REQUEST_CODE_INVITE);
But, as soon as I am clicking on the button which executes this code, a dialog pops up saying 'Unfortunately, Google Play Services has stopped'.
I have tried disabling, uninstalling and installing google play services again, and even restarting the phone, but no use.
No Exception is shown in android studio logs, so I am not able to figure out the problem is.
Please help.
There are a few issues here, and I'd also you to validate values.
getString requires resources. Assuming you are calling this from in an activity, you need to call
getResources().getString(R.....). You are likely getting null
returned which would result in an exception.
Although there is only 1 required parameter, you should fill out a few more to make sure you have a reasonable invitation, specifically setMessage(). Also, you can use setAccount() if you know the account, otherwise it will prompt.
I would also validate the input values. For example, log the string value you get for R.string.invitation_title to make sure you have set this correctly before you call the builder.
I was making a silly mistake which was leading to the error.
I was not initializing the GoogleApiClient before sending out the intent. Don't know how I missed it.
Here's the code that I was missing :
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(AppInvite.API)
.enableAutoManage(this, this)
.build();
Hope it helps future visitors to this page.
With the release of the 8.3 update, it seems that the
Person class (https://developers.google.com/android/reference/com/google/android/gms/plus/model/people/Person.html)
that we used before is replaced with a
GoogleSignInAccount class (https://developers.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInAccount)
Both seems to be similar, we can still get the user Display Name (getDisplayname() method) to say hello, and customize the application, but the getName() and hasBirthday features are missing.
That's something that is necessary in the application to fill the register form automatically.
Are these informations (birthday and first/last name) completely missing from the new API, or is there a workaround?
Thanks.
The Person resource now seems to be a part of Google+ API plus.model.people so in order to get social scopes, you would need to use the Google+ Sign In and .addApi(Plus.API) in GoogleApiClient.builder.
Simple GoogleSignInAccount only holds basic account information and if you are requesting social scopes, you need to include the red G+ sign in button (more information here).
I am trying to enable Saved Game in my Android game. However, I find that if I call
builder.addApi(Drive.API);
builder.addScope(Drive.SCOPE_APPFOLDER);
the "Select Account" dialog doesn't even shown at all, and I cannot therefore sign in.
Uncommenting both lines and everything works fine (sign in, leaderboard, achievement) except Save Game. Trying to get a Snapshot gives me the following error
01-11 23:30:14.549 18072-18488/? E/Evaderīš Must include Drive.SCOPE_APPFOLDER to use snapshots!
java.lang.IllegalStateException: Must include Drive.SCOPE_APPFOLDER to use snapshots!
Is this deprecated? This is the method recommended on https://developers.google.com/games/services/android/savedgames
I am working with LibGDX and the BaseGameUtils if that's relevant
If the code you included in your question is accurate, the problem is in how you are calling the Builder class.
The client is constructed using a builder pattern, so you need to update the return value of the previous call when creating the builder instance, such as: (notice there is only one semi-colon).
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.addApi(Drive.API).addScope(Drive.SCOPE_APPFOLDER)
.build();
The problem wasn't with the code whatsoever. It was the phone(test device).
I tested on another device and it worked flawlessly.
I updated uninstalled Google Play Store and Google Play Services updates, and re-installed them, and everything worked.
TLDR - Test on multiple devices. I'm not exactly sure why that happened on my device for my game only, but after performing the above, everything works.
Thanks Clayton Wilkinson
I use the Google+ Platform for Android with
PlusClient plusClient =
new PlusClient.Builder(this, this, this).setScopes(Scopes.PLUS_LOGIN).build();
In the onConnected-Listener I want to read the data of the logged in user
#Override
public void onConnected() {
super.onConnected();
Person person = plusClient.getCurrentPerson();
}
The method call getCurrentPerson returns null.
Has anyone managed to read the user-data?
You need to create an OAuth 2 client ID and add your Android app's developer (and probably production) signing keys to it, as described in the Google+ Getting Started guide.
I did the same thing but had not known to create the OAuth 2 client ID, and was getting null from that method (of course with no useful feedback in the logs). After creating the ID and adding my app's signing keys, the method returns an actual Person instance.
Even though you don't actually USE the client ID anywhere in your application, the act of adding your signing key in that interface apparently unlocks something on Google's servers and allows things to work.
Did you go through the setup steps outlined here?
You need to create an OAuth 2 client ID and add your Android app's developer (if you are releasing only add release key, otherwise development key will be enough) signing keys to it, as described in the Google+ Getting Started guide.
If you upgrade your API Console to New one, Go To "Consent Screen" and add Product Name(this is required)
Go to API Console "APIs & auth" -> "APIs" and enable "Google+ API"
it will work like a charm!!!