Skip to content Skip to sidebar Skip to footer

How Do I Switch Accounts Under The New Google Drive Android Api

My authorization flow in the new Google Drive Android API is as follows: Menu: SELECT ACCOUNT connect(); onConnectionFailed() result.startResolutionForResult() invokes AccountSel

Solution 1:

First, add the Plus.API:

mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(Drive.API).addApi(Plus.API).addScope(Drive.SCOPE_APPFOLDER).addConnectionCallbacks(this).addOnConnectionFailedListener(this).build();

Then you can switch accounts like this:

publicvoidonClick(View view) {
  if (view.getId() == R.id.sign_out_button) {
    if (mGoogleApiClient.isConnected()) {
      Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
      mGoogleApiClient.disconnect();
      mGoogleApiClient.connect();
    }
  }
}

For more, see here.

Solution 2:

Just call

mGoogleApiClient.clearDefaultAccountAndReconnect();

have a look at the docs.

This will call the onConnectionFailed callback that will present the layout to choose among the available Google accounts:

@OverridepublicvoidonConnectionFailed(ConnectionResult connectionResult) 
{
    if (connectionResult.hasResolution()) {
        try {                                              
            connectionResult.startResolutionForResult(this, RESOLVE_CONNECTION_REQUEST_CODE);
        } catch (IntentSender.SendIntentException e) {
            // Unable to resolve, message user appropriately
        }
    } else {                                           
        GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(), this, 0).show();
    }

}

Solution 3:

I realize I made quite a mess by opening two SO questions about essentially the same topic. So, it is a good time to consolidate the answers. I was searching for direct getter / setter methods in GDAA but found only the 'setter' - setAccountName()) - SO question 21583828 (actually did not, but Burcu helped me).

On the other side, 'getter' can be substituted by getting the account name from "onActivityResult()" - SO question 21501829

And yet another SO question - this one - on the same topic has been resolved as well.

So the conclusion is:

  1. get account from 'onActivityResult()'
  2. set account in 'setAccountName()'
  3. keep your current account email around, so you can detect a new one (should user decide to switch) and reset Google Account Client if necessary.

UPDATE 2014-11-04:

Here is a wrapper that I use to persist and manage the Google accounts within my app.

import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import com.google.android.gms.auth.GoogleAuthUtil;

publicclassGooAccMgr {
  privatestaticfinalStringACC_NAME="account_name";
  publicstaticfinalintFAIL= -1;
  publicstaticfinalintUNCHANGED=0;
  publicstaticfinalintCHANGED= +1;

  privateStringmCurrEmail=null;  // cache locallypublic Account[] getAllAccnts(Context ctx) {
    return AccountManager.get(acx(ctx)).getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
  }

  public Account getPrimaryAccnt(Context ctx) {
    Account[] accts = getAllAccnts(ctx);
    returnaccts== null || accts.length == 0 ? null : accts[0];
  }

  public Account getActiveAccnt(Context ctx) {
    return email2Accnt(ctx, getActiveEmail(ctx));
  }

  public String getActiveEmail(Context ctx) {
    if (mCurrEmail != null) {
      return mCurrEmail;
    }
    mCurrEmail = ctx == null ? null : pfs(ctx).getString(ACC_NAME, null);
    return mCurrEmail;
  }

  public Account email2Accnt(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;
        }
      }
    }
    returnnull;
  }

  /**
   * Stores a new email in persistent app storage, reporting result
   * @param ctx activity context
   * @param newEmail new email, optionally null
   * @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
   */publicintsetEmail(Context ctx, String newEmail) {
    intresult= FAIL;  // 0  0StringprevEmail= getActiveEmail(ctx);
    if        ((prevEmail == null) && (newEmail != null)) {
      result = CHANGED;
    } elseif ((prevEmail != null) && (newEmail == null)) {
      result = UNCHANGED;
    } elseif ((prevEmail != null) && (newEmail != null)) {
      result = prevEmail.equalsIgnoreCase(newEmail) ? UNCHANGED : CHANGED;
    }
    if (result == CHANGED) {
      mCurrEmail = newEmail;
      pfs(ctx).edit().putString(ACC_NAME, newEmail).apply();
    }
    return result;
  }

  private Context acx(Context ctx) {
    returnctx== null ? null : ctx.getApplicationContext();
  }
  private SharedPreferences pfs(Context ctx) {
    returnctx== null ? null : PreferenceManager.getDefaultSharedPreferences(acx(ctx));
  }
}

Hat-tip to Alex Lockwood for initial inspiration. Unfortunately, I can't find reference to his original code.

Solution 4:

It sounds like you are relying on the default account selection. In this setup, the user is prompted once to select an account, and this status is remembered.

If you want to provide account switching capabilities in your app, you need to instead launch the account picker from your own app and provide the account name selected when you instantiate the GoogleApiClient.

You could persist the last selected account name in shared preferences so you remember it until the next time the user switches accounts.

Solution 5:

if you use GoogleApiClient, just call mGoogleApiClient.clearDefaultAccountAndReconnect().

if you use DriveClient with GoogleSignInAccount (drive library 16.0.0), try this.

// try connect DrivefunstartSignIn() {
    val requiredScopes = HashSet<Scope>()
    requiredScopes.add(Drive.SCOPE_FILE)
    requiredScopes.add(Drive.SCOPE_APPFOLDER)
    val account = GoogleSignIn.getLastSignedInAccount(this)
    if (account != null && account.grantedScopes.containsAll(requiredScopes)) {
        // TODO: Get DriveClient and DriveResourceClient
    } else {
        val option = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestScopes(Drive.SCOPE_FILE, Drive.SCOPE_APPFOLDER)
            .build()
        val client = GoogleSignIn.getClient(this, option)
        startActivityForResult(client.signInIntent, REQUEST_CODE_SIGN_IN)
    }
}

// try change accountfunchangeAccount() {
    val option = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
    .build()
    val client = GoogleSignIn.getClient(activity, option)
    client.signOut()
        .addOnSuccessListener {
            Log.d(TAG, "signOut success")
            // Try again sign-in
            startSignIn()
        }
        .addOnFailureListener {
            Log.e(TAG, "signOut failed $it")
        }
    }

Post a Comment for "How Do I Switch Accounts Under The New Google Drive Android Api"