android - GoogleAuthUtil: get access token that will provide an email address? -
i'm unable access token provide email address. i'm using googleauthutil. (the result says token invalid)
i use this:
mgoogleapiclient = new googleapiclient.builder (cordova.getactivity().getapplicationcontext()) .addconnectioncallbacks (this) .addonconnectionfailedlistener (this) .addapi (games.api) .addscope (games.scope_games) .addapi(plus.api) .addscope(plus.scope_plus_profile) .addscope(plus.scope_plus_login) .build ();
, this:
scope = "oauth2:" + scopes.profile + " " + "email";
dropping " email" works give me valid access token -- there's no email address in response.
here code.
package com.flyingsoftgames.googleplayservices; import com.google.android.gms.common.connectionresult; import com.google.android.gms.common.scopes; import com.google.android.gms.common.api.googleapiclient; import com.google.android.gms.common.api.googleapiclient.connectioncallbacks; import com.google.android.gms.common.api.googleapiclient.onconnectionfailedlistener; import com.google.android.gms.common.googleplayservicesutil; import com.google.android.gms.games.players; import com.google.android.gms.games.games; import com.google.android.gms.auth.googleauthexception; import com.google.android.gms.auth.googleauthutil; import com.google.android.gms.auth.userrecoverableauthexception; import com.google.android.gms.auth.googleplayservicesavailabilityexception; import com.google.android.gms.plus.account; import com.google.android.gms.plus.plus; import org.apache.cordova.callbackcontext; import org.apache.cordova.cordovainterface; import org.apache.cordova.cordovawebview; import org.apache.cordova.cordovaplugin; import org.apache.cordova.pluginresult; import org.apache.cordova.pluginresult.status; import org.json.jsonarray; import org.json.jsonexception; import org.json.jsonobject; import android.content.context; import android.content.intent; import android.content.intentsender.sendintentexception; import android.app.activity; import android.os.asynctask; import android.os.bundle; import org.apache.cordova.*; import java.io.ioexception; import android.util.log; public class googleplayservices extends cordovaplugin implements googleapiclient.connectioncallbacks, googleapiclient.onconnectionfailedlistener { private static final string log_tag = "googleplayservices"; private static final int req_sign_in_required = 55664; public static googleapiclient mgoogleapiclient = null; public callbackcontext tryconnectcallback = null; public string accesstoken = ""; private int connectionattempts = 0; @override public void onconnectionfailed (connectionresult result) { string errormessage = result.tostring(); log.w (log_tag, errormessage); connectionattempts += 1; if (!result.hasresolution() || connectionattempts >= 2) { log.w (log_tag, "error: no resolution. google play services connection failed."); tryconnectcallback.error ("error: " + errormessage + "."); tryconnectcallback = null; return; } try { result.startresolutionforresult (cordova.getactivity(), result.geterrorcode()); } catch (sendintentexception e) { // there error resolution intent. try again. mgoogleapiclient.connect (); } } @override public void onconnected (bundle connectionhint) { string maccountname = plus.accountapi.getaccountname(mgoogleapiclient); new retrievetokentask().execute (maccountname); games.setviewforpopups (mgoogleapiclient, webview); } public void onactivityresult (int requestcode, int responsecode, intent intent) { if (!mgoogleapiclient.isconnecting()) mgoogleapiclient.connect (); } @override public void onconnectionsuspended (int cause) { mgoogleapiclient.connect (); } public boolean execute (string action, jsonarray inputs, callbackcontext callbackcontext) throws jsonexception { if ("getplayerid".equals(action)) { string playerid = games.players.getcurrentplayerid (mgoogleapiclient); callbackcontext.sendpluginresult (new pluginresult (pluginresult.status.ok, playerid)); } else if ("tryconnect".equals(action)) { tryconnect (callbackcontext); } else if ("getaccesstoken".equals(action)) { callbackcontext.sendpluginresult (new pluginresult (pluginresult.status.ok, accesstoken)); } return true; } // tryconnect runs callback value of false if google play services isn't available. public void tryconnect (callbackcontext callbackcontext) { boolean isgpsavailable = (googleplayservicesutil.isgoogleplayservicesavailable(cordova.getactivity()) == connectionresult.success); if (!isgpsavailable) { callbackcontext.sendpluginresult (new pluginresult (pluginresult.status.ok, false)); return; } tryconnectcallback = callbackcontext; mgoogleapiclient = new googleapiclient.builder (cordova.getactivity().getapplicationcontext()) .addconnectioncallbacks (this) .addonconnectionfailedlistener (this) .addapi (games.api) .addscope (games.scope_games) .addapi(plus.api) .addscope(plus.scope_plus_profile) .addscope(plus.scope_plus_login) .build (); mgoogleapiclient.connect (); } private class retrievetokentask extends asynctask<string, void, string> { @override protected string doinbackground (string... params) { string accountname = params[0]; string scope = "oauth2:" + scopes.profile + " " + "email"; context context = cordova.getactivity().getapplicationcontext(); try { accesstoken = googleauthutil.gettoken (context, accountname, scope); } catch (ioexception e) { string errormessage = e.getmessage(); log.e (log_tag, errormessage); if (tryconnectcallback != null) tryconnectcallback.error ("error: " + errormessage + "."); tryconnectcallback = null; } catch (userrecoverableauthexception e) { cordova.getactivity().startactivityforresult (e.getintent(), req_sign_in_required); } catch (googleauthexception e) { string errormessage = e.getmessage(); log.e (log_tag, errormessage); if (tryconnectcallback != null) tryconnectcallback.error ("error: " + errormessage + "."); tryconnectcallback = null; } return accesstoken; } @override protected void onpostexecute (string newaccesstoken) { super.onpostexecute (newaccesstoken); accesstoken = newaccesstoken; if (tryconnectcallback != null) { string playerid = games.players.getcurrentplayerid (mgoogleapiclient); tryconnectcallback.sendpluginresult (new pluginresult (pluginresult.status.ok, playerid)); tryconnectcallback = null; } } } }
it seems clearing app's permission in https://security.google.com/settings/security/permissions?hl=en trigger re-authorization screen, access token received .gettoken is stale. googleauthutil.cleartoken (context, accesstoken);
needs used clear old token, or old token must time out. thus, can do:
accesstoken = googleauthutil.gettoken(context, accountname, scope); googleauthutil.cleartoken (context, accesstoken); accesstoken = googleauthutil.gettoken(context, accountname, scope);
however:
it seems resolves after few iterations of re-launching app, because googleauthutil.gettoken asynchronous when new permissions required, , 2 separate permission screens pop up: 1 google (triggered googleauthutil.gettoken
, 1 google+ (triggered googleapiclient.builder
).
edit: using accountpicker
class eliminates need use googleapiclient.builder
!
Comments
Post a Comment