We're under Android (Jellybean and higher), and we've got an app which need to use OAuth2 with Google for authentication.
I simplified the login activity, but it's looking like that:
AccountManager mAccountManager;
// [...]
Account account = new Account("[email protected]", "com.google");
// same with professional email managed by Google as [email protected]
// real code recovers accounts with mAccountManager.getAccountsByType("com.google")
mAccountManager = AccountManager.get(getBaseContext());
mAccountManager.getAuthToken(account, "oauth2:https://www.googleapis.com/auth/userinfo.email", null, MyActivity.this, new AccountManagerCallback<Bundle>() {
@Override
public void run(AccountManagerFuture<Bundle> accountManagerFuture) {
try {
String token = accountManagerFuture.getResult().getString(AccountManager.KEY_AUTHTOKEN);
// exception occurs here
// [...]
} catch (Exception e) {
Log.e("account", "exception occurs", e);
}
}
}, null);
When we call accountManagerFuture.getResult()
, it fires this exception:
android.accounts.AuthenticatorException: UNREGISTERED_ON_API_CONSOLE
at android.accounts.AccountManager.convertErrorToException(AccountManager.java:2024)
at android.accounts.AccountManager.access$400(AccountManager.java:144)
at android.accounts.AccountManager$AmsTask$Response.onError(AccountManager.java:1867)
at android.accounts.IAccountManagerResponse$Stub.onTransact(IAccountManagerResponse.java:69)
at android.os.Binder.execTransact(Binder.java:446)
I cannot find neither doc about this nor other people with the same exception, and I'm quite confused: the call to AccountManager.getAuthToken
only provides an account (name and type), a scope, and a callback method, there's no parameter to specify an app or something I could customize in the dev API console.
I'm sure I'm missing something, but what?
Well, I finally figured it out. Not sure if I misread the documentation or if there are missing links, but anyway.
Fact is that when you sign a APK and then ask Google for a OAuth2 token, you have to register your signed app through the dev console. It's a security measure based on the app package name and the sha1 fingerprint.
To do that, you have to :
signingReport
task under your root project and run it - the SHA1 fingerprint will show in the text output;And voila!
For information, the only official documentation I found explaining the why and how of the two final steps is here: https://developers.google.com/drive/android/auth
For anyone still struggling with this, here's what worked for me:
If you enroll your app into the Google Play App Signing program, then your KeyStore is not used de facto to sign the application once it reaches the play store - that's why the fingerprints don't match.
Google removes your certificate and creates a new signing certificate that is used to sign your APK.
In the Play Console go to Release Management -> App signing
If you opted in to Google Play App Signing, you'll see 2 certificates there along with all of their fingerprints. Use the App Signing Certificate fingerprint instead of the Upload Certificate which is your KeyStore.
Don't have the reputation to comment on the accepted answer...
Registering my app in the google dev console wasn't working for me. It turned out that since I was using the debug gradle build, I had to append ".debug" to the package name in google dev console.
I found this out by debugging the Android AccountManager code. When I stepped into the code, I noticed the variable for my app's package name had ".debug" at the end of it. So instead of using the actual package name "com.package.name" in the google dev console, I changed it to "com.package.name.debug" which fixed the UNREGISTERED_ON_API_CONSOLE exception for me.
The reason for this is because my debug buildType in gradle had 'applicationIdSuffix ".debug"'.
Thanks Xavier Portebois, your answer really helped. I had to do two more steps.
Thanks for the informative answer!
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