Вызов игровых сервисов Google Play из фрагмента

Я реализовал некоторые функции Google Play Game в моем приложении для Android в качестве отдельного Activity, и теперь я пытаюсь переписать мой код как фрагмент Action Bar Sherlock. Я использую предоставленный код GameHelper в своем фрагменте.

Автоматический знак работает правильно. Инициированный пользователем вход не выполняется, потому что вызов StartResolutionForResult в GameHelper возвращается к активности onActivityResult Activity, а не к фрагменту. Я проверил все это, используя Log.D. Мое понимание этого ограничено – что мне делать, чтобы исправить это? Я попытался передать другой контекст, но StartResolutionForResult, по-видимому, принимает только Activity как свой контекст.

API игровых сервисов Google Play должен быть привязан к жизненному циклу Activity, а не к жизненному циклу фрагмента. Если ваша игровая логика находится во Фрагменте, вы можете реализовать onActivityResult в Activity и вызвать оттуда свой фрагмент. Взгляните на наш образец номера номера номера , который, помимо того, чтобы быть захватывающей и захватывающей игрой </ sarcasm>, демонстрирует, как бороться с фрагментами. Каждый экран типа A Number является фрагментом, и они обмениваются информацией с Activity по мере необходимости.

В этом конкретном случае все взаимодействие с API игр производится Activity. Тем не менее, вы могли бы также сделать Activity GamesClient объектом GamesClient для фрагмента, чтобы он мог реализовать свою собственную логику.

Во всех случаях не забудьте сохранить постоянную ссылку на GamesClient в фрагменте дольше, чем вам нужно. Вероятно, лучше всего запросить его из Activity (через интерфейс, например), когда вам это нужно. Это делается для предотвращения утечки во время жизненного цикла Activity.

Вы можете onActivityResult вызов onActivityResult на фрагмент следующим образом:

Мы должны поразрядно сдвинуть код запроса на 16 бит.

 public static final int REQUEST_CHECK_SETTINGS = 1<<16; //shifted 1 16 bits 

Добавьте это к активности, которой принадлежит фрагмент.

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); } 

Примечание. Я понял это из исходного кода onActivityResult в FragmentActivity. Он сдвигает бит requestCode 16 вправо.

 /** * Dispatch incoming result to the correct fragment. */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { mFragments.noteStateNotSaved(); int index = requestCode>>16; if (index != 0) { index--; final int activeFragmentsCount = mFragments.getActiveFragmentsCount(); if (activeFragmentsCount == 0 || index < 0 || index >= activeFragmentsCount) { Log.w(TAG, "Activity result fragment index out of range: 0x" + Integer.toHexString(requestCode)); return; } final List<Fragment> activeFragments = mFragments.getActiveFragments(new ArrayList<Fragment>(activeFragmentsCount)); Fragment frag = activeFragments.get(index); if (frag == null) { Log.w(TAG, "Activity result no fragment exists for index: 0x" + Integer.toHexString(requestCode)); } else { frag.onActivityResult(requestCode&0xffff, resultCode, data); } return; } super.onActivityResult(requestCode, resultCode, data); } 

Примечание 2: Я был бы рад, если бы кто-нибудь мог сказать мне, почему использование этого метода будет плохим подходом

Я не уверен, насколько аналогичен API для игр по сравнению с соседними (я думаю, это должно сработать), но при создании GoogleApiClient для Nearside я обнаружил, что объекты, переданные в обратные вызовы ошибок (Status, ConnectionResult), удобно Parcelable. Поэтому я создал Activity, который можно запустить для обработки этих ошибок, а затем передать любой результат, который он получит обратно вызывающему.

https://gist.github.com/damien5314/c13ce47bca035c517dfbdfb2af488a73

Применение:

 Nearby.Messages.publish(mNearbyApi, mMessage) .setResultCallback(new ResultCallback<Status>() { @Override public void onResult(@NonNull Status status) { Log.d(TAG, "Nearby publish result: " + getStatusCodeString(status.getStatusCode())); if (status.getStatusCode() > 0) { Intent intent = ResolveErrorActivity.buildIntent(getContext(), status); startActivityForResult(intent, ResolveErrorActivity.REQUEST_RESOLVE_ERROR); } } }); 

Пока вы вызываете startActivityForResult из фрагмента, он должен получить результат, как обычно.

Сдвиг 1 << 16 больше не поддерживается.

Вы можете попробовать позвонить из своего Fragment

 private static final int REQUEST_CHECK_SETTINGS = 0x1; final ResolvableApiException rae = (ResolvableApiException) e; startIntentSenderForResult(rae.getResolution().getIntentSender(), REQUEST_CHECK_SETTINGS, null, 0, 0, 0, null); 

И получить результат на Fragment's onActivtyResult вот так:

  @Override public void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { // Check for the integer request code originally supplied to startIntentSenderForResult(). case REQUEST_CHECK_SETTINGS: switch (resultCode) { case Activity.RESULT_OK: // Do smth break; case Activity.RESULT_CANCELED: // show Error break; } break; } }