11

新しい Google Drive Android API での私の認証フローは次のとおりです。

  1. メニュー: アカウントを選択
  2. 接続();
  3. onConnectionFailed() result.startResolutionForResult() は AccountSelectDialog / DriveAuthorization を呼び出します
  4. onConnected() 自分のことをする

魅力のように機能します。アカウントを切り替える目的で繰り返します。

  1. メニュー: アカウントを選択
  2. 接続();
  3. onConnected()

ここでは、「結果」でonConnectionFailed()を取得してstartResolutionForResult()を呼び出すことがないため、 AccountSelectDialogにアクセスする機会がありません。今回は何が欠けていますか?

4

5 に答える 5

8

まず、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();
    }
  }
}

詳細については、こちらを参照してください。

于 2014-04-05T13:46:29.983 に答える
7

電話するだけ

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();
    }

}
于 2015-06-11T09:12:10.547 に答える
6

本質的に同じトピックに関する 2 つの SO の質問を開くことで、かなり混乱したことに気付きました。ですから、答えをまとめる良い機会です。GDAA で直接の getter/setter メソッドを探していましたが、'setter' - setAccountName()) - SO question 21583828 (実際には見つかりませんでしたが、Burcu が助けてくれました) しか見つかりませんでした。

一方、「getter」は、「onActivityResult()」からアカウント名を取得することで置き換えることができます - SO question 21501829

そして、同じトピックに関するさらに別の SO の質問 - this one - も解決されました。

したがって、結論は次のとおりです。

  1. 「onActivityResult()」からアカウントを取得
  2. 「setAccountName()」でアカウントを設定
  3. 現在のアカウントのメールを保管しておくと、新しいメールを検出し (ユーザーが切り替えを決定した場合)、必要に応じて Google アカウント クライアントをリセットできます。

2014 年 11 月 4 日更新:

これは、アプリ内で 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));
  }
}

最初のインスピレーションを与えてくれた Alex Lockwood に敬意を表します。残念ながら、彼の元のコードへの参照が見つかりません。

于 2014-02-08T03:17:58.397 に答える
0

デフォルトのアカウント選択に依存しているようです。このセットアップでは、ユーザーはアカウントを選択するように 1 回求められ、このステータスが記憶されます。

アプリでアカウント切り替え機能を提供する場合は、代わりに独自のアプリからアカウント ピッカーを起動し、GoogleApiClient をインスタンス化するときに選択したアカウント名を提供する必要があります。

共有設定で最後に選択したアカウント名を保持して、次回ユーザーがアカウントを切り替えるまで覚えておくことができます。

于 2014-02-07T01:05:47.647 に答える
0

GoogleApiClient を使用する場合は、 を呼び出すだけmGoogleApiClient.clearDefaultAccountAndReconnect()です。

GoogleSignInAccount (ドライブ ライブラリ 16.0.0) で DriveClient を使用している場合は、これを試してください。

// 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")
        }
    }
于 2018-12-03T09:00:07.193 に答える