每当我在第一个应用程序启动周期中第一次运行代码时
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(context)
.addApi(Drive.API)
.addScope(Drive.SCOPE_APPFOLDER) // required for App Folder sample
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
我可以看到以下帐号选择器。
但是,如果以前的连接成功,并且我第二次在第二次应用启动周期时再次运行相同的代码。
帐户选择器不会再次弹出。 GoogleApiClient
将使用帐户名称,我在之前的应用启动周期中选择。
我希望每次都能弹出我的帐号选择器。
我遇到了How to Clear GoogleApiClient Default Account and Credentials
建议的解决方案对我的案例不起作用。
mGoogleApiClient.clearDefaultAccountAndReconnect()
如果我已连接上一个应用周期,并且我在当前应用周期中第一次调用上述代码,则会出现以下异常。
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.common.internal.zzx.zza(Unknown Source)
at com.google.android.gms.common.api.internal.zzj.clearDefaultAccountAndReconnect(Unknown Source)
以下代码也无法使用。
if (mGoogleApiClient.isConnected()) {
// No chance to execute this code, if you run this code during app launch.
mGoogleApiClient.clearDefaultAccountAndReconnect();
} else {
// No account chooser will pop up if you had been connected in previous app life cycle
mGoogleApiClient.connect();
}
我可以知道,每次调用connect时,如何强制GoogleApiClient提示帐户选择器UI?
答案 0 :(得分:12)
在GDAA和REST Api中,您有两种选择:
1 /您没有指定帐户,底层系统将对其进行管理
2 /您自己管理帐户。
如果您使用第一种方法,则永远不会知道您的应用用户是谁。你只能清理'该帐户通过clearDefaultAccountAndReconnect
。选择对话框再次弹出,用户可以选择(添加)另一个帐户。
如果您需要知道当前所选的用户帐户(即缓存/持久性),您必须自己管理帐户选择,因为您可以看到here (for REST)或here (for GDAA) - 只需按照{{1跟踪和REQ_ACCPICK
类。这样你就可以完全掌控了。
所以,对你的问题的简短回答是你弹出
UT.AM
自己活动并提供结果
startActivityForResult(AccountPicker.newChooseAccountIntent(null,
null, new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, true, null, null, null, null),
REQ_ACCPICK);
到email = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME)
,如下:
setAccountName(email)
祝你好运
答案 1 :(得分:4)
我想我迟到了,但这就是我解决它的方法。
在我开始显示构建器的Google SignIn Intent之前。
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
这样做:
if (mGoogleApiClient.hasConnectedApi(Auth.GOOGLE_SIGN_IN_API)) {
mGoogleApiClient.clearDefaultAccountAndReconnect();
}
由于mGoogleApiClient
由于某种原因存储登录用户。因此,即使您正在重新创建mGoogleApiClient.isConnected()
的实例,如果执行mGoogleApiClient
它也可能无法正常工作。但是,这将强制它清除已选择的用户。
经过测试,确实有效。
答案 2 :(得分:2)
看起来目前无法清除默认帐户,除非已连接GoogleApiClient。我们可以通过引入一个布尔标志来解决这个问题,告诉我们是否需要清除默认帐户。
private boolean mClearDefaultAccount;
@Override
public void onConnectionFailed(ConnectionResult result) {
if (!mIntentInProgress && result.hasResolution()) {
try {
mIntentInProgress = true;
mClearDefaultAccount = false;
startIntentSenderForResult(result.getResolution().getIntentSender(),
GOOGLE_PLUS, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
mIntentInProgress = false;
// report error
}
} else if (!mIntentInProgress) {
// report error
}
}
@Override
public void onConnected(Bundle bundle) {
if (mClearDefaultAccount) {
mClearDefaultAccount = false;
mGoogleApiClient.clearDefaultAccountAndReconnect();
return;
}
// connected...
}
在调用mGoogleApiClient.connect()
之前,相应地设置布尔状态标志,以提示帐户根据需要使用当前默认帐户。
请注意,如果用户在设备上只有一个帐户,则可能会发生冗余connect()
来电。
protected void connectToGoogleApi(final boolean clearDefaultAccount) {
if (clearDefaultAccount && mGoogleApiClient.isConnected()) {
mClearDefaultAccount = false;
mGoogleApiClient.clearDefaultAccountAndReconnect();
} else {
mGoogleApiClient.connect();
}
}
答案 3 :(得分:1)
如果API客户端未连接或连接,我发现重新创建API客户端更容易,然后再次提示输入帐户。
答案 4 :(得分:1)
通过上述解决方案的混合和匹配,我得到了它:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
})
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(@Nullable Bundle bundle) {
mGoogleApiClient.clearDefaultAccountAndReconnect(); // To remove to previously selected user's account so that the choose account UI will show
}
@Override
public void onConnectionSuspended(int i) {
}
})
.addApi(Auth.GOOGLE_SIGN_IN_API, new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestEmail().build())
.build();
希望能帮助他人节省一些时间。 =)
答案 5 :(得分:0)
每次调用connect 时,强制执行GoogleApiClient以提示帐户选择器UI的方法都非常糟糕。如果您有更好的方法,请告诉我们。
它围绕这个想法而建立。
onConnectionFailed
。onConnected
中,我们可以检查onConnectionFailed
是否至少被触发一次。如果没有,我们会致电clearDefaultAccountAndReconnect
。这是这个想法的完整代码。
public class GoogleApiClientFragment extends Fragment implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
public static GoogleApiClientFragment newInstance() {
return new GoogleApiClientFragment();
}
/**
* Handles resolution callbacks.
*/
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RequestCode.REQUEST_GOOGLE_API_CLIENT_CONNECT && resultCode == Activity.RESULT_OK) {
mGoogleApiClient.connect();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this.getContext())
.addApi(Drive.API)
.addScope(Drive.SCOPE_APPFOLDER)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
accountPickerShown = false;
mGoogleApiClient.connect();
}
}
@Override
public void onPause() {
super.onPause();
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
}
@Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "GoogleApiClient connected");
if (accountPickerShown == false && mGoogleApiClient.isConnected()) {
mGoogleApiClient.clearDefaultAccountAndReconnect();
}
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "GoogleApiClient connection suspended");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "GoogleApiClient connection failed: " + connectionResult.toString());
if (!connectionResult.hasResolution()) {
// show the localized error dialog.
GoogleApiAvailability.getInstance().getErrorDialog(this.getActivity(), connectionResult.getErrorCode(), 0).show();
return;
}
try {
accountPickerShown = (connectionResult.getErrorCode() == ConnectionResult.SIGN_IN_REQUIRED);
connectionResult.startResolutionForResult(this.getActivity(), RequestCode.REQUEST_GOOGLE_API_CLIENT_CONNECT);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
private boolean accountPickerShown = false;
private static final String TAG = "GoogleApiClientFragment";
private GoogleApiClient mGoogleApiClient;
}
答案 6 :(得分:0)
接受的解决方案确实有效(如果您想将更新版本的API导入您的应用程序,您还必须包含google-play-services-auth
api),但帐户选择器将会以不同的风格出现,可能会使用户感到困惑或担忧。
如果您希望保持UI统一并且不想包含google-play-services-auth
API,我提供了2个备用解决方案。
您可以拨打mGoogleApiClient.clearDefaultAccountAndReconnect()
,然后只要您想强制用户选择帐户,就可以通过拨打mGoogleApiClient.disconnect()
立即断开连接。通过这样做,您可以在下次用户连接时调用mGoogleApiClient.connect()
连接(强制帐户选择器)。当您希望触发用户再次选择帐户的特定事件时,此功能非常有用。
另一种(更普遍有用的)解决方案是以相同的方式执行以下操作(在后台线程中,可能是AsyncTask
)而不是最终的代码块:
mGoogleApiClient.blockingConnect();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.clearDefaultAccountAndReconnect();
}
这将避免您看到的空指针异常,并将显式强制帐户选择器。这是有点奇怪,因为你连接两次,但它的工作原理。
如果Google明确地在GoogleApiClient
中提供此功能,那就太好了。
答案 7 :(得分:0)
问题是您退出了内部活动,而不是从 signIn 中退出,但是如果您每次都在登录前退出,则问题将得到解决。 简单的! ,只需添加
mGoogleSignInClient.signOut();
在您开始登录之前,即:
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
这将在您登录之前注销任何用户。