3

Android アプリにいくつかの Google Play ゲーム サービス機能を別のアクティビティとして実装しました。現在、コードを (Action Bar Sherlock) フラグメントとして書き直そうとしています。提供された GameHelper コードをフラグメントで使用しています。

自動サインインは正しく機能します。GameHelper の StartResolutionForResult 呼び出しがフラグメントではなくアクティビティの onActivityResult に戻るため、ユーザーが開始したサインインは失敗します。Log.D を使用して、これらすべてを確認しました。これについての私の理解は限られています - これを修正するにはどうすればよいですか? 別のコンテキストを渡そうとしましたが、StartResolutionForResult はアクティビティのみをコンテキストとして受け入れるようです。

4

4 に答える 4

8

Google Play ゲーム サービス API は、フラグメントのライフサイクルではなく、アクティビティのライフサイクルに関連付ける必要があります。ゲーム ロジックがフラグメント内にある場合、アクティビティに onActivityResult を実装し、そこからフラグメントを呼び出すことができます。タイプ A ナンバー チャレンジのサンプルを見てみましょう。これは、非常にエキサイティングで中毒性のあるゲーム</皮肉>であることに加えて、フラグメントの処理方法を示しています。Type A Number の各画面はフラグメントであり、必要に応じてアクティビティと通信します。

この特定のケースでは、ゲーム API とのすべての対話はアクティビティによって行われます。ただし、Activity がGamesClientオブジェクトを Fragment に渡して、独自のロジックを実装できるようにすることもできます。

GamesClientどのような場合でも、必要以上に長く Fragment に永続的な参照を保持しないように注意してください。Activity必要なときはいつでも から (たとえば、インターフェイスを介して)クエリを実行するのがおそらく最善です。これは、Activity のライフサイクル中にリークするのを防ぐためです。

于 2013-06-07T17:48:21.803 に答える
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);
}

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:この方法を使用することが悪いアプローチである理由を誰かが教えてくれたらうれしいです

于 2016-02-01T13:15:08.413 に答える
0

ゲーム用 API が Nearby と比較してどの程度似ているかはわかりませんが (これはうまくいくと思います)、Nearby 用の GoogleApiClient を作成すると、エラー コールバック (Status、ConnectionResult) で渡されるオブジェクトが便利に Parcelable であることがわかりました。そこで、これらのエラーを処理するために起動できるアクティビティを作成し、受け取った結果を呼び出し元に渡します。

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、通常どおり結果が得られます。

于 2016-07-07T22:29:27.280 に答える