Как включить учетные записи в новом API Android для Google Диска
Мой поток авторизации в новом API Google Диске Android выглядит следующим образом:
- Меню: ВЫБРАТЬ АККАУНТ
- подключения();
- onConnectionFailed()
result.startResolutionForResult()
вызывает AccountSelectDialog/DriveAuthorization
- onConnected() делай свои вещи
Работает как шарм. Теперь повторяем с целью переключения учетных записей:
- Меню: ВЫБРАТЬ АККАУНТ
- подключения();
- onConnected()
Здесь у меня нет шансов добраться до AccountSelectDialog, так как я никогда не получаю onConnectionFailed() с "результатом", чтобы вызвать startResolutionForResult(). Что мне не хватает на этот раз?
Ответы
Ответ 1
Просто позвоните
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();
}
}
Ответ 2
Сначала добавьте 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();
}
}
}
Подробнее см. здесь.
Ответ 3
Я понимаю, что я сделал довольно беспорядок, открыв два SO-вопроса по существу той же теме. Итак, самое подходящее время для консолидации ответов. Я искал методы прямого getter/setter в GDAA, но нашел только "setter" - setAccountName()) - SO вопрос 21583828 (на самом деле этого не делал, но Burcu помог мне).
С другой стороны, "getter" можно заменить, получив имя учетной записи от "onActivityResult()" - SO question 21501829
И еще один вопрос SO - этот - по той же теме был также решен.
Итак, вывод:
- получить учетную запись из 'onActivityResult()'
- установить учетную запись в 'setAccountName()'
- сохраняйте электронную почту своего аккаунта, чтобы вы могли обнаружить новую (если пользователь решит переключиться) и reset Клиент аккаунта Google, если это необходимо.
ОБНОВЛЕНИЕ 2014-11-04:
Вот оболочка, которую я использую для сохранения и управления учетными записями 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));
}
}
Шляпа для Алекс Локвуда для первоначального вдохновения. К сожалению, я не могу найти ссылку на его оригинальный код.
Ответ 4
Похоже, вы полагаетесь на выбор учетной записи по умолчанию. В этой настройке пользователю предлагается один раз выбрать учетную запись, и этот статус запоминается.
Если вы хотите предоставить возможности переключения учетных записей в своем приложении, вам нужно вместо этого запустить сборщик учетных записей из своего собственного приложения и указать имя учетной записи, выбранную при создании экземпляра GoogleApiClient.
Вы можете сохранить последнее выбранное имя учетной записи в общих настройках, чтобы вы помнили ее до следующего раза, когда пользователь переключает учетные записи.
Ответ 5
если вы используете 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")
}
}