2

私はAndroidアプリのFacebook統合に取り組んでおり、煩わしさを軽減するために、アプリケーションのメインロジックからFacebookロジックを分離するシングルトンクラスを作成しようとしています。

アプリケーションのさまざまな部分(エントリポイント、非同期タスクなど)からこのクラスを呼び出せるようにしたいと思います。この時点で、最初にapplicationcontextをコンテキストとして初期化関数を呼び出します。この初期化の後、私は例えばを呼び出すことができるようにしたいと思います。FacebookSession.getInstance().login()およびFacebookSession.getInstance().requestWithQuery(examplestring)

問題は、まともなドキュメントが見つからないことです。Facebookの公式サンプルでさえ、廃止された古いFacebookオブジェクトを使用しています。私はこのクラスを見つけたコードのさまざまな部分と一緒に投げ、これを思いついた:

package be.ugent.zeus.hydra.util.facebook;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import com.facebook.HttpMethod;
import com.facebook.Request;
import com.facebook.Session;
import com.facebook.SessionState;

public class FacebookSession {

    private static final String APP_ID = "hidden";
    private static final String ACCESS_TOKEN = "hidden";
    private static FacebookSession fbSession;
    public static final String TAG = "FACEBOOK";
    private Activity activity;
    private static Session.StatusCallback statusCallback = new SessionStatusCallback();

    protected FacebookSession() {
    }

    public static void initialize(Context context) {

        Session session = Session.getActiveSession();
        if (session == null) {
            session = new Session.Builder(context)
                .setApplicationId(APP_ID)
                .build();
        }
        Session.setActiveSession(session);
    }

    public static FacebookSession getInstance() {

        if (fbSession == null) {
            fbSession = new FacebookSession();
        }

        return fbSession;
    }

    public Session getSession() {
        return Session.getActiveSession();
    }

    public void tryOpenSession(Activity activity) {
        Session session = Session.openActiveSession(activity, false, statusCallback);
        Session.setActiveSession(session);
    }

    public void login(Activity activity) {
        Session session = Session.getActiveSession();

        if (!session.isOpened() && !session.isClosed()) {
            Session.openActiveSession(activity, true, statusCallback);
        }
    }

    public void logout() {
        Session session = Session.getActiveSession();

        if (!session.isClosed()) {
            session.closeAndClearTokenInformation();
        }
    }

    public boolean isOpen() {

        Session session = Session.getActiveSession();
        return session.isOpened();
    }

    public Request requestWithQuery(String query) {

        Bundle bundle = new Bundle();
        bundle.putString("q", query);

        return requestWithGraphPath("/fql", bundle, "GET");
    }

    private Request requestWithGraphPath(String path, Bundle bundle, String method) {

        // Get the session
        Session session = Session.getActiveSession();

        // No session? Try to open one without user interaction
        if (session == null) {
            session = Session.openActiveSession(activity, false, statusCallback);
            Session.setActiveSession(session);
        }

        // Still no session? Use the default key
        if (session == null) {
            bundle.putString("access_token", ACCESS_TOKEN);
        }

        return new Request(session, path, bundle, HttpMethod.valueOf(method));

    }

    private static class SessionStatusCallback implements Session.StatusCallback {

        @Override
        public void call(Session session, SessionState state, Exception exception) {

            Log.i(TAG, state.toString());

            switch (state) {
                case CLOSED:
                case CLOSED_LOGIN_FAILED:
                    session.closeAndClearTokenInformation();
                    break;
                default:
                    break;
            }
        }
    }
}

queryingpartはかなりうまく機能しますが、セッションは機能しません。たとえば、ログイン関数を呼び出すと、アクティブなセッションはnullになりますが、アプリケーションのエントリポイントでapplicationcontextを使用してセッションを初期化しました。

具体的には、この質問があります:

  • これは、セッションの状態を追跡する(試行する)「良い」方法ですか?このようにできますか?もしそうなら、それがうまくいかないという私が間違っていることは何ですか?

そしてフォローアップの質問として:

  • そうでない場合は、アプリケーションの存続期間中またはアプリケーションセッション間でセッションを追跡する正しい方法は何ですか?

前もって感謝します。

4

1 に答える 1

4

問題を100%理解しているとは限りませんが、FWIWでは、次のことがうまくいきます。

どこかのアクティビティで:

Session.openActiveSession(MyActivity.this, true, new Session.StatusCallback() {
    @Override
    public void call(Session session, SessionState state, Exception exception) {
        if(session.isOpened()) {
            Log.d(TAG, "FB session opened successfully");
        } else {
            Log.d(TAG, "FB session not opened ... " + exception.toString());
        }
    }
});

そして、どこか別の場所(異なるActivity、AsyncTaskなど)がSession.getActiveSession()を使用してセッションにアクセスします。

Session session = Session.getActiveSession();
if(session!=null && session.isOpened()) {
    Request.executeMyFriendsRequestAsync(session, new Request.GraphUserListCallback() {

        @Override
        public void onCompleted(List<GraphUser> users, Response response) {
            for(GraphUser u : users) {
                Log.d(TAG, ""+u.getId()+ ": " + u.getName());
            }
        }

    });
}

したがって、FacebookのSessionクラスは、必要なものを提供しているように見えます(アクティブなセッション「シングルトンスタイル」へのアクセス)

HTH

于 2013-03-19T01:31:19.340 に答える