谷歌提供了BaseGameUtils
库,并建议我们扩展其BaseGameActivity
。但是,这个类会在游戏启动时自动登录。如果玩家不想或无法连接到他的谷歌账号,这可能非常耗时。
因此我不想使用这个功能。相反,我想提供一个登录按钮。只有当玩家点击该按钮时,他才能连接。从那时起,每次玩家启动游戏,他都会自动连接到他的谷歌账户,而不需要点击任何按钮。 我该怎么做?
谷歌提供了BaseGameUtils
库,并建议我们扩展其BaseGameActivity
。但是,这个类会在游戏启动时自动登录。如果玩家不想或无法连接到他的谷歌账号,这可能非常耗时。
因此我不想使用这个功能。相反,我想提供一个登录按钮。只有当玩家点击该按钮时,他才能连接。从那时起,每次玩家启动游戏,他都会自动连接到他的谷歌账户,而不需要点击任何按钮。 我该怎么做?
好的,我已经弄清楚了,默认情况下,最大自动登录次数为3,这意味着如果用户取消3次,则该应用程序将不再自动登录(除非您清除应用程序的数据)。它存储在GameHelper.java
中。
// Should we start the flow to sign the user in automatically on startup? If so, up to
// how many times in the life of the application?
static final int DEFAULT_MAX_SIGN_IN_ATTEMPTS = 3;
int mMaxAutoSignInAttempts = DEFAULT_MAX_SIGN_IN_ATTEMPTS;
它还提供了一个设置这个最大数量的函数
public void setMaxAutoSignInAttempts(int max) {
mMaxAutoSignInAttempts = max;
}
如果您不想尝试自动登录,只需调用此函数。
这是当您不想扩展BaseGameActivity时的情况。
gameHelper = new GameHelper(this, GameHelper.CLIENT_GAMES);
gameHelper.enableDebugLog(true);
gameHelper.setup(this);
gameHelper.setMaxAutoSignInAttempts(0);
或者如果您扩展了BaseGameActivity
getGameHelper().setMaxAutoSignInAttempts(0);
DEFAULT_MAX_SIGN_IN_ATTEMPTS
被设置为 3
真的让我感到非常困惑。 - Alex Lockwood在GameHelper.java
文件中,有一个名为mConnectOnStart
的布尔属性,默认设置为true。只需将其改为false
:
boolean mConnectOnStart = false;
此外,还提供了一种从类外部管理此属性的方法:
// Not recommended for general use. This method forces the "connect on start"
// flag to a given state. This may be useful when using GameHelper in a
// non-standard sign-in flow.
public void setConnectOnStart(boolean connectOnStart) {
debugLog("Forcing mConnectOnStart=" + connectOnStart);
mConnectOnStart = connectOnStart;
}
您可以使用上述方法来自定义您的登录流程。
在我这种情况下,与您类似,我不想在第一次登录时自动连接。但是如果用户以前已登录,则希望自动连接。为了实现这一点,我将位于BaseGameActivity
类中的getGameHelper()
方法更改为:
public GameHelper getGameHelper() {
if (mHelper == null) {
mHelper = new GameHelper(this, mRequestedClients);
mHelper.enableDebugLog(mDebugLog);
googlePlaySharedPref = getSharedPreferences("GOOGLE_PLAY",
Context.MODE_PRIVATE);
boolean wasSignedIn = googlePlaySharedPref.getBoolean("WAS_SIGNED_IN", false);
mHelper.setConnectOnStart(wasSignedIn);
}
return mHelper;
}
每次从 BaseGameActivity
的 onStart()
方法中调用 getGameHelper()
方法。在上面的代码中,我只是添加了共享偏好以保留用户之前是否已登录的信息,并根据该情况调用了 setConnectOnStart()
方法。"WAS_SIGNED_IN"
(如果您使用不同名称定义了其他内容,则可以使用其他名称)共享偏好设置为 true。您可以在 BaseGameActivity
类中的 onSignInSucceeded()
方法中执行此操作。...
public class GameHelper implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
....
// Whether to automatically try to sign in on onStart(). We only set this
// to true when the sign-in process fails or the user explicitly signs out.
// We set it back to false when the user initiates the sign in process.
boolean mConnectOnStart = false;
...
/** Call this method from your Activity's onStart(). */
public void onStart(Activity act) {
mActivity = act;
mAppContext = act.getApplicationContext();
debugLog("onStart");
assertConfigured("onStart");
SharedPreferences sp = mAppContext.getSharedPreferences(GAMEHELPER_SHARED_PREFS, Context.MODE_PRIVATE);
mConnectOnStart = sp.getBoolean(KEY_AUTO_SIGN_IN, false);
if (mConnectOnStart) {
...
}
...
/** Sign out and disconnect from the APIs. */
public void signOut() {
...
// Ready to disconnect
debugLog("Disconnecting client.");
mConnectOnStart = false;
SharedPreferences.Editor editor = mAppContext.getSharedPreferences(GAMEHELPER_SHARED_PREFS, Context.MODE_PRIVATE).edit();
editor.putBoolean(KEY_AUTO_SIGN_IN, false);
editor.commit();
mConnecting = false;
mGoogleApiClient.disconnect();
}
...
/**
* Starts a user-initiated sign-in flow. This should be called when the user
* clicks on a "Sign In" button. As a result, authentication/consent dialogs
* may show up. At the end of the process, the GameHelperListener's
* onSignInSucceeded() or onSignInFailed() methods will be called.
*/
public void beginUserInitiatedSignIn() {
debugLog("beginUserInitiatedSignIn: resetting attempt count.");
resetSignInCancellations();
mSignInCancelled = false;
mConnectOnStart = true;
SharedPreferences.Editor editor = mAppContext.getSharedPreferences(GAMEHELPER_SHARED_PREFS, Context.MODE_PRIVATE).edit();
editor.putBoolean(KEY_AUTO_SIGN_IN, true);
editor.commit();
if (mGoogleApiClient.isConnected()) {
...
}
...
private final String GAMEHELPER_SHARED_PREFS = "GAMEHELPER_SHARED_PREFS";
private final String KEY_SIGN_IN_CANCELLATIONS = "KEY_SIGN_IN_CANCELLATIONS";
private final String KEY_AUTO_SIGN_IN = "KEY_AUTO_SIGN_IN";
...
}
在 onCreate 中调用 getGameHelper().setConnectOnStart(false);
。
实际上,谷歌的代码与您在第二段所说的完全一样。
我想提供一个登录按钮。只有当玩家点击该按钮时,才会连接玩家。从那时起,每次玩家启动游戏时,他都会自动连接到他的Google帐户,而无需点击任何按钮。我该怎么做?
Helper.setup方法创建客户端
onStart查看内部布尔值以进行自动登录。如果用户先前已连接(并且用户没有注销或断开连接时没有错误),则尝试重新建立登录。
beginUserInitiatedSignIn将设置自动登录布尔值,如果成功启动连接,则会设置自动登录布尔值
onStop仅会优雅地终止连接,不会重置布尔值
因此,当您的应用程序启动时,用户看到登录过程的唯一方式是在推送按钮之前某种方式调用了beginUserInitiatedSignIn。
确保您的beginUserInitiatedSignIn不在onStart方法中,并且除非通过其他方式调用,否则不要调用它,除非您的登录按钮被点击且用户未登录。
@Override
protected void onCreate(Bundle b) {
super.onCreate(b);
mHelper = new GameHelper(this);
if (mDebugLog) {
mHelper.enableDebugLog(mDebugLog, mDebugTag);
}
mHelper.setup(this, mRequestedClients, mAdditionalScopes);
}
@Override
protected void onStart() {
super.onStart();
mHelper.onStart(this);
}
@Override
protected void onStop() {
super.onStop();
mHelper.onStop();
}
protected void beginUserInitiatedSignIn() {
mHelper.beginUserInitiatedSignIn();
}
来自BaseGameUtil类
/** * 游戏的示例基类。此实现负责设置GamesClient对象并管理其生命周期。子类只需要覆盖@link{#onSignInSucceeded}和@link{#onSignInFailed}抽象方法。 * 当用户单击登录按钮时,子类应调用@link{#beginUserInitiatedSignIn}以启动登录流程。默认情况下,此类仅实例化GamesClient对象。 * 如果还需要PlusClient或AppStateClient对象,请调用BaseGameActivity(int)构造函数并指定所需的客户端。 * 例如,要请求PlusClient和GamesClient,请使用BaseGameActivity(CLIENT_GAMES | CLIENT_PLUS)。 * 要请求所有可用客户端,请使用BaseGameActivity(CLIENT_ALL)。或者,您也可以通过@link{#setRequestedClients}指定所需的客户端, * 但必须在调用@link{#onCreate}之前这样做,否则调用将无效。 * * 作者:Bruno Oliveira(Google)
onStart
或者setup()
方法可以自动管理我们的登录过程(隐式调用beginUserInitiatedSignIn()
)。不管怎样,我已经找到了如何禁用这个过程,详见我的回答。 - Hải Phong