This is a tricky question, as I donβt have time to completely repeat and analyze your code. And, without starting it, I do not see anything obvious.
But, since I have this application and it works in my application, I would like to help. Unfortunately, the Google Apps connection and authorization code are scattered across all my fragments and actions. So, I tried to create a fictitious activity and pull out all the things in it. "All things" I mean the wrapper of the account manager (GA) and the associated account selection code.
The result is about 300 lines of gibberish that can work, but I make no complaints. Look and good luck.
package com.......; import android.accounts.Account; import android.accounts.AccountManager; import android.app.Activity; import android.app.Dialog; import android.app.DialogFragment; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentSender; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.util.Log; import android.widget.Toast; import com.google.android.gms.auth.GoogleAuthUtil; import com.google.android.gms.common.AccountPicker; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.common.api.GoogleApiClient; public class GooApiClient extends Activity implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks { private static final String DIALOG_ERROR = "dialog_error"; private static final String REQUEST_CODE = "request_code"; private static final int REQ_ACCPICK = 1; private static final int REQ_AUTH = 2; private static final int REQ_RECOVER = 3; private GoogleApiClient mGooApiClient; private boolean mIsInAuth; //block re-entrancy @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (checkPlayServices() && checkUserAccount()) { gooInit(); gooConnect(true); } } @Override public void onConnected(Bundle bundle) { Log.d("_", "connected"); } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult result) { Log.d("_", "failed " + result.hasResolution()); if (!mIsInAuth) { if (result.hasResolution()) { try { mIsInAuth = true; result.startResolutionForResult(this, REQ_AUTH); } catch (IntentSender.SendIntentException e) { suicide("authorization fail"); } } else { suicide("authorization fail"); } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent it) { Log.d("_", "activity result " + requestCode + " " + resultCode); switch (requestCode) { case REQ_AUTH: case REQ_RECOVER: { mIsInAuth = false; if (resultCode == Activity.RESULT_OK) { gooConnect(true); } else if (resultCode == RESULT_CANCELED) { suicide("authorization fail"); } return; } case REQ_ACCPICK: { // return from account picker if (resultCode == Activity.RESULT_OK && it != null) { String emil = it.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); if (GA.setEmil(this, emil) == GA.CHANGED) { gooInit(); gooConnect(true); } } else if (GA.getActiveEmil(this) == null) { suicide("selection failed"); } return; } } super.onActivityResult(requestCode, resultCode, it); // DO NOT REMOVE } private boolean checkPlayServices() { Log.d("_", "check PS"); int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (status != ConnectionResult.SUCCESS) { if (GooglePlayServicesUtil.isUserRecoverableError(status)) { mIsInAuth = true; errorDialog(status, LstActivity.REQ_RECOVER); } else { suicide("play services failed"); } return false; } return true; } private boolean checkUserAccount() { String emil = GA.getActiveEmil(this); Account accnt = GA.getPrimaryAccnt(this, true); Log.d("_", "check user account " + emil + " " + accnt); if (emil == null) { // no emil (after install) if (accnt == null) { // multiple or no accounts available, go pick one accnt = GA.getPrimaryAccnt(this, false); Intent it = AccountPicker.newChooseAccountIntent(accnt, null, new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, true, null, null, null, null ); this.startActivityForResult(it, LstActivity.REQ_ACCPICK); return false; //--------------------->>> } else { // there only one goo account registered with the device, skip the picker GA.setEmil(this, accnt.name); } // UNLIKELY BUT POSSIBLE, emil OK, but the account have been removed since (through settings) } else { accnt = GA.getActiveAccnt(this); if (accnt == null) { accnt = GA.getPrimaryAccnt(this, false); Intent it = AccountPicker.newChooseAccountIntent(accnt, null, new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, true, null, null, null, null ); this.startActivityForResult(it, LstActivity.REQ_ACCPICK); return false; //------------------>>> } } return true; } private void gooInit(){ String emil = GA.getActiveEmil(this); Log.d("_", "goo init " + emil); if (emil != null){ mGooApiClient = new GoogleApiClient.Builder(this) .setAccountName(emil).addApi(com.google.android.gms.drive.Drive.API) .addScope(com.google.android.gms.drive.Drive.SCOPE_FILE) .addConnectionCallbacks(this).addOnConnectionFailedListener(this) .build(); } } private void gooConnect(boolean bConnect) { Log.d("_", "goo connect " + bConnect); if (mGooApiClient != null) { if (!bConnect) { mGooApiClient.disconnect(); } else if (! (mGooApiClient.isConnecting() || mGooApiClient.isConnected())){ mGooApiClient.connect(); } } } private void suicide(String msg) { GA.removeActiveAccnt(this); Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); finish(); } private void errorDialog(int errorCode, int requestCode) { Bundle args = new Bundle(); args.putInt(DIALOG_ERROR, errorCode); args.putInt(REQUEST_CODE, requestCode); ErrorDialogFragment dialogFragment = new ErrorDialogFragment(); dialogFragment.setArguments(args); dialogFragment.show(getFragmentManager(), "errordialog"); } public static class ErrorDialogFragment extends DialogFragment { public ErrorDialogFragment() { } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { int errorCode = getArguments().getInt(DIALOG_ERROR); int requestCode = getArguments().getInt(DIALOG_ERROR); return GooglePlayServicesUtil.getErrorDialog(errorCode, getActivity(), requestCode); } @Override public void onDismiss(DialogInterface dialog) { getActivity().finish(); } } private static class GA { private static final String ACC_NAME = "account_name"; public static final int FAIL = -1; public static final int UNCHANGED = 0; public static final int CHANGED = +1; private static String mCurrEmil = null; // cache locally private static String mPrevEmil = null; // cache locally public static Account[] getAllAccnts(Context ctx) { return AccountManager.get(acx(ctx)).getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE); } public static Account getPrimaryAccnt(Context ctx, boolean bOneOnly) { Account[] accts = getAllAccnts(ctx); if (bOneOnly) return accts == null || accts.length != 1 ? null : accts[0]; return accts == null || accts.length == 0 ? null : accts[0]; } public static Account getActiveAccnt(Context ctx) { return emil2Accnt(ctx, getActiveEmil(ctx)); } public static String getActiveEmil(Context ctx) { if (mCurrEmil != null) { return mCurrEmil; } mCurrEmil = ctx == null ? null : pfs(ctx).getString(ACC_NAME, null); return mCurrEmil; } public static Account getPrevEmil(Context ctx) { return emil2Accnt(ctx, mPrevEmil); } public static Account emil2Accnt(Context ctx, String emil) { if (emil != null) { Account[] accounts = AccountManager.get(acx(ctx)).getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE); for (Account account : accounts) { if (emil.equalsIgnoreCase(account.name)) { return account; } } } return null; } /** * Stores a new email in persistent app storage, reporting result * @param newEmil new email, optionally null * @param ctx activity context * @return FAIL, CHANGED or UNCHANGED (based on the following table) * OLD NEW SAVED RESULT * ERROR FAIL * null null null FAIL * null new new CHANGED * old null old UNCHANGED * old != new new CHANGED * old == new new UNCHANGED */ public static int setEmil(Context ctx, String newEmil) { int result = FAIL; // 0 0 mPrevEmil = getActiveEmil(ctx); if ((mPrevEmil == null) && (newEmil != null)) { result = CHANGED; } else if ((mPrevEmil != null) && (newEmil == null)) { result = UNCHANGED; } else if ((mPrevEmil != null) && (newEmil != null)) { result = mPrevEmil.equalsIgnoreCase(newEmil) ? UNCHANGED : CHANGED; } if (result == CHANGED) { mCurrEmil = newEmil; pfs(ctx).edit().putString(ACC_NAME, newEmil).apply(); } return result; } public static void removeActiveAccnt(Context ctx) { mCurrEmil = null; pfs(ctx).edit().remove(ACC_NAME).apply(); } private static Context acx(Context ctx) { return ctx == null ? null : ctx.getApplicationContext(); } private static SharedPreferences pfs(Context ctx) { return ctx == null ? null : PreferenceManager.getDefaultSharedPreferences(acx(ctx)); } } }
By the way, I know how to write "e-mail", "Emil" just turned out to be my uncle's name, and I could not resist :-)
UPDATE (2015-Apr-11):
I recently visited a code that handles authorization in Google Drive and account switching. The result can be found here , and it supports both REST and GDAA apis.