Как я могу заставить Службы Play Play автоматически войти в систему при запуске?
Google предоставляет библиотеку BaseGameUtils
, а рекомендует нам расширять ее BaseGameActivity
. Тем не менее, этот класс заставляет игру автоматически входить в игру всякий раз, когда начинается игра. Если игрок не хочет или не может подключиться к своей учетной записи Google, это может быть очень трудоемким в начале игры.
Так что я не хочу эту функцию. Вместо этого я хочу предоставить кнопку входа. Игрок подключается только при нажатии этой кнопки. И с этого момента каждый раз, когда игрок начинает игру, он автоматически подключается к своей учетной записи Google, не нажимая ни одной кнопки. Как я могу это сделать?
Ответы
Ответ 1
ОК, я понял, по умолчанию, максимальное время автоматического входа 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);
Ответ 2
В файле 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;
}
Вы можете использовать описанный выше метод, чтобы настроить свой вход в систему.
В моем случае, подобно вам, я не хочу автоматически подключаться в первый раз. Но если пользователь был ранее подписан, я хочу автоматически подключиться. Чтобы это стало возможным, я изменил метод getGameHelper()
, который находится в классе BaseGameActivity
:
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;
}
Каждый раз, getGameHelper()
метод вызывается из onStart()
в BaseGameActivity
. В приведенном выше коде я просто добавил общее предпочтение сохранить, если пользователь был ранее подписан. И назвал метод setConnectOnStart()
в соответствии с этим случаем.
Наконец, не забудьте установить "WAS_SIGNED_IN"
(или что-то еще, если вы определили с другим именем), разделяемое предпочтение true после того, как пользователь выполнил входной сигнал. Вы можете сделать это в методе onSignInSucceeded()
в классе BaseGameActivity
.
Надеюсь, это поможет вам. Удачи.
Ответ 3
Я сделал это так, я не знаю, это лучший способ сделать это. Я изменил класс GameHelper, чтобы он сохранял предпочтения пользователя в общих настройках:
...
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 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";
...
}
Смотрите https://github.com/playgameservices/android-samples/blob/master/FAQ.txt строка 54, почему вы автоматически входите в систему
Ответ 4
Вызвать getGameHelper().setConnectOnStart(false);
из onCreate
Ответ 5
Фактически, код из Google работает точно так же, как вы говорите во втором абзаце.
Я хочу предоставить кнопку входа. Игрок подключается только при нажатии этой кнопки. И с этого момента каждый раз, когда игрок начинает игру, он автоматически подключается к своей учетной записи Google, не нажимая ни одной кнопки. Как я могу это сделать?
-
Метод Helper.setup создает клиентов
-
onStart смотрит на внутреннее логическое значение для автоматического входа. Если пользователь был ранее подключен (и пользователь не выходил из системы или не было ошибки при отключении), он попытается восстановить вход.
-
beginUserInitiatedSignIn установит логическое значение автоматического входа в систему, если инициировано успешное соединение.
-
onStop будет только изящно прекращать соединения, он не reset логический
Таким образом, единственный способ, с помощью которого пользователь видит входной сигнал, когда запускается приложение, - это если beginUserInitiatedSignIn каким-то образом вызывается перед нажатием кнопки.
Убедитесь, что ваш startUserInitiatedSignIn не находится в вашем методе 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) * constructor и указать запрашиваемых клиентов. Например, для запроса * PlusClient и GamesClient, используйте BaseGameActivity (CLIENT_GAMES | CLIENT_PLUS). * Чтобы запросить всех доступных клиентов, используйте BaseGameActivity (CLIENT_ALL). * В качестве альтернативы вы также можете указать запрашиваемых клиентов через * @link {#setRequestedClients}, но вы должны сделать это до @link {#onCreate} * вызывается, иначе вызов не будет иметь эффекта. * * @author Бруно Оливейра (Google)