从片段中调用Google Play游戏服务

时间:2013-06-07 00:45:30

标签: android android-fragments google-play-games

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

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

4 个答案:

答案 0 :(得分:8)

Google Play游戏服务API应该与Activity的生命周期相关联,而不是Fragment的生命周期。如果你的游戏逻辑在Fragment中,你可以在Activity上实现onActivityResult并从那里调用你的Fragment。看看我们的Type A Number Challenge样本,它除了是一个非常令人兴奋和令人上瘾的游戏< / sarcasm>之外,还演示了如何处理片段。 Type A Number中的每个屏幕都是一个片段,它们根据需要与Activity通信。

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

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

答案 1 :(得分: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;
        }
    }

答案 2 :(得分: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);
}

注意:我已经从FragmentActivity中onActivityResult的源代码中找到了这个。它将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:如果有人能告诉我为什么使用这种方法会是一种糟糕的方法,我会很高兴

答案 3 :(得分:0)

我不确定游戏的API与Nearby相比有多相似(我觉得这应该有用),但在为Nearby创建GoogleApiClient时,我发现错误回调(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,它就会像往常一样得到结果。