Как переключить учетную запись в НОВОМ API Google Диска для Android

Моя процедура авторизации в новом API Google Диска для Android выглядит следующим образом:

  1. Меню: ВЫБРАТЬ УЧЕТНУЮ ЗАПИСЬ
  2. соединять();
  3. onConnectionFailed () result.startResolutionForResult () вызывает AccountSelectDialog / DriveAuthorization
  4. onConnected () делай свое дело

Работает как шарм. Теперь повторяем с целью переключения учетных записей:

  1. Меню: ВЫБРАТЬ УЧЕТНУЮ ЗАПИСЬ
  2. соединять();
  3. onConnected ()

Здесь у меня нет возможности попасть в AccountSelectDialog, поскольку я никогда не получаю onConnectionFailed () с результатом для вызова startResolutionForResult (). Что мне не хватает на этот раз?


person seanpj    schedule 06.02.2014    source источник


Ответы (5)


Просто позвони

mGoogleApiClient.clearDefaultAccountAndReconnect();

ознакомьтесь с документами.

Это вызовет обратный вызов onConnectionFailed, который представит макет для выбора среди доступных учетных записей Google:

@Override
public void onConnectionFailed(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();
    }

}
person Xavi Gil    schedule 11.06.2015
comment
Спасибо, это работает, но моему приложению по-прежнему необходимо знать активную учетную запись (адрес электронной почты), выбранную пользователем в процессе. Управление им на уровне приложения (согласно моему ответу ниже) - 1 / беспорядок, 2 / требуется разрешение GET_ACCOUNTS. Любые идеи? Кстати, когда я задал вопрос, упомянутого вами метода не существовало. - person seanpj; 19.07.2015
comment
Сейчас, 16.05.26. Просто позвони . mGoogleApiClient.clearDefaultAccountAndReconnect (); / clearDefaultAccountAndReconnect устарел. - person Brownsoo Han; 26.05.2016
comment
@BrownsooHan Где ты это видишь? Нет никаких указаний в коде или в документации. - person Bevor; 25.06.2017

Сначала добавьте Plus.API:

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

Затем вы можете переключать учетные записи следующим образом:

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

Дополнительную информацию см. здесь.

person Mark    schedule 05.04.2014
comment
Я должен добавить, я не знаю, почему это работает - не следует ли просто изменить учетную запись Plus? - но похоже, что это так ... Был бы признателен, если бы кто-нибудь еще подтвердил. - person Mark; 05.04.2014
comment
Это сработало и для меня. Мне интересно, очищает ли он учетные записи для Google Диска только потому, что вы проходите mGoogleApiClient. - person Randy; 24.06.2014

Я понимаю, что напортачил, задав два SO-вопроса, по сути, на одну и ту же тему. Итак, сейчас хорошее время для обобщения ответов. Я искал прямые методы получения / установки в GDAA, но нашел только «сеттер» - setAccountName ()) - ТАК вопрос 21583828 (на самом деле нет, но Burcu мне помог).

С другой стороны, 'getter' можно заменить, получив имя учетной записи из "onActivityResult ()" - ТАК вопрос 21501829

И еще один ТАК вопрос - этот - тоже по той же теме.

Итак, вывод такой:

  1. получить аккаунт из onActivityResult ()
  2. установить учетную запись в 'setAccountName ()'
  3. сохраните адрес электронной почты своей текущей учетной записи, чтобы вы могли обнаружить новую (если пользователь решит переключиться) и при необходимости сбросить клиент учетной записи Google.

ОБНОВЛЕНИЕ, 4 ноября 2014 г .:

Вот оболочка, которую я использую для сохранения и управления учетными записями Google в моем приложении.

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;

public class GooAccMgr {
  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 String mCurrEmail = null;  // cache locally

  public Account[] getAllAccnts(Context ctx) {
    return AccountManager.get(acx(ctx)).getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
  }

  public Account getPrimaryAccnt(Context ctx) {
    Account[] accts = getAllAccnts(ctx);
    return accts == 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;
        }
      }
    }
    return null;
  }

  /**
   * 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
   */
  public int setEmail(Context ctx, String newEmail) {
    int result = FAIL;  // 0  0

    String prevEmail = getActiveEmail(ctx);
    if        ((prevEmail == null) && (newEmail != null)) {
      result = CHANGED;
    } else if ((prevEmail != null) && (newEmail == null)) {
      result = UNCHANGED;
    } else if ((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) {
    return ctx == null ? null : ctx.getApplicationContext();
  }
  private SharedPreferences pfs(Context ctx) {
    return ctx == null ? null : PreferenceManager.getDefaultSharedPreferences(acx(ctx));
  }
}

Наконечник шляпы Алексу Локвуду за первоначальное вдохновение. К сожалению, я не могу найти ссылку на его исходный код.

person seanpj    schedule 08.02.2014

Похоже, вы полагаетесь на выбор учетной записи по умолчанию. В этой настройке пользователю один раз предлагается выбрать учетную запись, и этот статус запоминается.

Если вы хотите предоставить возможность переключения учетных записей в своем приложении, вам необходимо вместо этого запустить средство выбора учетной записи из собственного приложения и указать имя учетной записи, выбранное при создании экземпляра GoogleApiClient.

Вы можете сохранить последнее выбранное имя учетной записи в общих настройках, чтобы помнить его до следующего раза, когда пользователь сменит учетную запись.

person Cheryl Simon    schedule 07.02.2014
comment
Спасибо за ваш ответ. К сожалению, это не то, что мне нужно. Мой вопрос был связан с переносом на НОВЫЙ Google Drive Android API (GDAA) developers.google.com/drive/ android из Drive SDK v2 (SDKV2). В SDKV2 я могу запустить средство выбора учетной записи startActivityForResult (newChooseAccountIntent (), ...). В GDAA я должен делать это так, как вы упомянули, что приводит к запутанному коду с избыточностью. Таким образом, вопрос был не в том, как обойтись, а в том, чего-то мне не хватает в GDAA. Извините за то, что не уточнил в первый раз. - person seanpj; 07.02.2014
comment
В GDAA, если вы не указываете имя учетной записи, используется выбор учетной записи по умолчанию. Если учетная запись по умолчанию еще не выбрана, пользователю будет предложено выбрать ее. По истечении этого времени всегда будет использоваться эта учетная запись по умолчанию. В настоящее время нет способа сбросить это. Если вы хотите полностью поддерживать несколько учетных записей и переключаться между ними, вам необходимо самостоятельно выполнить логику выбора учетной записи. - person Cheryl Simon; 08.02.2014
comment
Спасибо, Шерил, я добавил еще один ответ ниже, просто чтобы убрать беспорядок, который я создал. - person seanpj; 08.02.2014
comment
Привет, Шерил, я хочу использовать учетную запись, которой нет на устройстве, например, стороннюю учетную запись. Это возможно ? - person Umang Kothari; 22.12.2014

если вы используете GoogleApiClient, просто позвоните mGoogleApiClient.clearDefaultAccountAndReconnect().

если вы используете DriveClient с GoogleSignInAccount (библиотека дисков 16.0.0), попробуйте это.

// try connect Drive
fun startSignIn() {
    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 account
fun changeAccount() {
    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")
        }
    }
person Brownsoo Han    schedule 03.12.2018