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!

see: https://github.com/agamemnus/googleplaytoken


Comments

Popular posts from this blog

ruby on rails - RuntimeError: Circular dependency detected while autoloading constant - ActiveAdmin.register Role -

c++ - OpenMP unpredictable overhead -

javascript - Wordpress slider, not displayed 100% width -