#android #google-play-services #google-play-games
#Android #google-play-сервисы #google-play-games
Вопрос:
Я работаю над приложением, использующим сервисы Google Play Games. В настоящее время я работаю над активностью на рабочем столе, и я хочу, чтобы поток входа в систему работал так же, как flappy bird.
В flappy bird (это всего лишь пример, я уверен, что многие другие приложения тоже работают подобным образом)…
- Нет кнопки входа
- Если пользователь нажимает на таблицу лидеров или кнопку «Оценить», он попросит вас войти в систему.
- Если вы не вошли в систему, вы все равно можете играть в автономном режиме
Я хочу, чтобы мой код реализовал это, но у меня возникли некоторые трудности. Во-первых, мое приложение продолжает просить меня войти в систему каждый раз, когда я начинаю действие, оно не помнит, что я ранее входил в систему. Я был бы признателен за помощь в моем следующем коде.
Вот мой код на данный момент:
public class HomeScreenActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener {
private Button playButton, leaderboardButton;
private Context appContext;
private static final int GAME_INTENT = 1000;
private GoogleApiClient mGoogleApiClient;
// Request code to use when launching the resolution activity
private static final int REQUEST_RESOLVE_ERROR = 1001;
private static final int REQUEST_LEADERBOARD = 1002;
// Unique tag for the error dialog fragment
private static final String DIALOG_ERROR = "dialog_error";
// Bool to track whether the app is already resolving an error
private boolean mResolvingError = false;
private static final String STATE_RESOLVING_ERROR = "resolving_error";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_screen_layout);
mResolvingError = savedInstanceState != null
amp;amp; savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false);
appContext = getApplicationContext();
findViews();
attachListeners();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Games.API)
.addApi(Plus.API)
.addScope(Games.SCOPE_GAMES)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onStart() {
super.onStart();
if (!mResolvingError) {
mGoogleApiClient.connect();
}
}
@Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError);
}
private void findViews() {
playButton = (Button) findViewById(R.id.play_button);
leaderboardButton = (Button) findViewById(R.id.leaderboard_button);
}
private void attachListeners() {
playButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(appContext, InGameActivity.class);
startActivityForResult(i, GAME_INTENT);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case GAME_INTENT:
// upload data to leaderboards
break;
case REQUEST_RESOLVE_ERROR:
mResolvingError = false;
if (resultCode == RESULT_OK) {
// Make sure the app is not already connected or attempting to
// connect
if (!mGoogleApiClient.isConnecting()
amp;amp; !mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
break;
}
}
@Override
public void onConnectionFailed(ConnectionResult result) {
if (mResolvingError) {
// Already attempting to resolve an error.
return;
} else if (result.hasResolution()) {
try {
mResolvingError = true;
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (SendIntentException e) {
// There was an error with the resolution intent. Try again.
mGoogleApiClient.connect();
}
} else {
// Show dialog using GooglePlayServicesUtil.getErrorDialog()
showErrorDialog(result.getErrorCode());
mResolvingError = true;
}
}
@Override
public void onConnected(Bundle arg0) {
Log.d("LOG", " onConnected ");
leaderboardButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(
mGoogleApiClient, getString(R.string.leaderboard_highest_score)), REQUEST_LEADERBOARD);
}
});
}
@Override
public void onConnectionSuspended(int arg0) {
Log.d("LOG", " onConnectionSuspended ");
leaderboardButton.setOnClickListener(null);
}
/* Creates a dialog for an error message */
private void showErrorDialog(int errorCode) {
// Create a fragment for the error dialog
ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
// Pass the error that should be displayed
Bundle args = new Bundle();
args.putInt(DIALOG_ERROR, errorCode);
dialogFragment.setArguments(args);
dialogFragment.show(getFragmentManager(), "errordialog");
}
/* Called from ErrorDialogFragment when the dialog is dismissed. */
public void onDialogDismissed() {
mResolvingError = false;
}
/* A fragment to display an error dialog */
public static class ErrorDialogFragment extends DialogFragment {
public ErrorDialogFragment() { }
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the error code and retrieve the appropriate dialog
int errorCode = this.getArguments().getInt(DIALOG_ERROR);
return GooglePlayServicesUtil.getErrorDialog(errorCode,
this.getActivity(), REQUEST_RESOLVE_ERROR);
}
@Override
public void onDismiss(DialogInterface dialog) {
((HomeScreenActivity)getActivity()).onDialogDismissed();
}
}
}
Ответ №1:
Вам нужно будет поддерживать и проверять состояние самостоятельно, если вы не используете BaseGameUtils для выполнения входа и других задач, связанных с Play Games. Это довольно запутанно, но вы можете взглянуть на GameHelper
класс в этом пакете, чтобы увидеть, как Google это делает.
Я бы посоветовал вам использовать BaseGameUtils
пакет и вместо расширения BaseGameActivity
просто использовать GameHelper напрямую. Это избавляет от многих проблем при работе с сервисом Play Games.
Комментарии:
1. Не обращайте внимания на это, на самом деле я хотел спросить вот что: когда я захожу в класс BaseGameActivity, там говорится, что мне нужно заставить пользователя нажать кнопку для входа в игру через
beginUserInitiatedSignIn
но как flappybird автоматически регистрирует вас? У меня есть приложение flappy bird, и там вообще нет кнопки входа. Как они это сделали?>2. Просто, вы можете вызвать
beginUserInitiatedSignIn()
в ответ на любое событие, например, когда игра заканчивается (перед публикацией результатов в таблице лидеров). Однако в рекомендациях Google рекомендуется сохранять вход пользователя в систему на время работы приложения. Таким образом, вы выполняете вход при запуске (пользователю будет предложено выбрать учетную запись только при первом запуске), и это соединение остается активным до тех пор, пока ваше приложение не покинет передний план, и оно будет восстановлено, когда оно восстановит фокус.3. Кроме того, ваше приложение не находится в постоянном контакте с серверами Google, а скорее взаимодействует с приложением Play Games. Затем это приложение периодически синхронизируется с серверами (через приложение Play Services). Только некоторые функции, такие как сохранение в облаке, немедленно взаимодействуют с облаком и требуют активного подключения. Достижения и таблицы лидеров кэшируются в приложении Play Games, если подключение недоступно, при условии, что ваш игрок вошел в систему.
4. Я понимаю, хорошо. Я собираюсь изменить весь свой код, чтобы использовать BaseGameUtils. Спасибо за совет.