3

我已经在我的 Android 应用程序中将一些 Google Play 游戏服务功能实现为单独的 Activity,我现在正尝试将我的代码重写为(Action Bar Sherlock)片段。我在我的片段中使用提供的 GameHelper 代码。

自动登录正常工作。用户发起的登录失败,因为 GameHelper 中的 StartResolutionForResult 调用返回到 Activity 的 onActivityResult 而不是片段。我已经使用 Log.D 验证了所有这些。我对此的理解是有限的——我应该怎么做才能解决这个问题?我尝试过传递不同的上下文,但 StartResolutionForResult 似乎只接受一个 Activity 作为它的上下文。

4

4 回答 4

8

Google Play 游戏服务 API 应该绑定到 Activity 的生命周期,而不是 Fragment 的生命周期。如果您的游戏逻辑在 Fragment 中,您可以在 Activity 上实现 onActivityResult 并从那里调用您的 Fragment。看看我们的A 类数字挑战示例,它不仅是一款非常令人兴奋和令人上瘾的游戏</sarcasm>,还展示了如何处理碎片。Type A Number 中的每个屏幕都是一个片段,它们根据需要与 Activity 进行通信。

在这种特殊情况下,与游戏 API 的所有交互都是由 Activity 进行的。但是,您也可以让 Activity 将GamesClient对象交给 Fragment,以便它可以实现自己的逻辑。

在所有情况下,请记住不要将持久引用保留GamesClient在 Fragment 中超过您需要的时间。最好在需要时从Activity(例如通过接口)查询它。这是为了防止它在 Activity 的生命周期中泄漏。

于 2013-06-07T17:48:21.803 回答
4

不再支持移位 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 上捕获结果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;
        }
    }
于 2017-07-01T16:33:42.600 回答
1

您可以将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);
}

注意:我从onActivityResultFragmentActivity 的源代码中发现了这一点。它将 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:如果有人能告诉我为什么使用这种方法会是一种不好的方法,我会很高兴

于 2016-02-01T13:15:08.413 回答
0

我不确定 Games 的 API 与 Nearby 相比有多相似(我认为这应该可以),但是在为 Nearby 创建 GoogleApiClient 时,我发现在错误回调(状态、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从 Fragment 调用,它就应该像往常一样得到结果。

于 2016-07-07T22:29:27.280 回答