Q:

Facebook session singleton usage

I'm working on Facebookintegration for my Android app and to reduce the hassle, I'm trying to create a singleton class to seperate the facebook logic from the main logic of my application.
I'd like to be able to call this class from different parts of my application (entrypoint, asynctasks, ...). At this moment, I call the initialize function first with the applicationcontext as context. After this initialization I'd like to be able to call eg. FacebookSession.getInstance().login() and FacebookSession.getInstance().requestWithQuery(examplestring). 
The problem is that I just can't find decent documentation. Even the facebook official samples uses the old Facebook object, which is deprecated. I threw this class together with different parts of code I could find and I came up with this:
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;
            }
        }
    }
}

The queryingpart works pretty neat, but the sessions don't. For example, if I call the login function, the active session is null, however I did initialize the Session with the applicationcontext in the entry point of my application.
Concrete, I have this question:

Is this the 'good' way of (trying) to keep track of the Session state? Can it be done this way? If so, what I'm doing wrong that it just doesn't work?

And as a follow-up question:

If not, then what is the correct way to keep track of a Session during either the application life time and otherwise between application sessions?

Thanks in advance.

A:

I'm not 100% certain I understand the problem, but FWIW, the following works for me:
In an Activity somewhere:

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());
        }
    }
});

And then, somewhere else (different Activity, AsyncTask, whatever) access the session with 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());
            }
        }

    });
}

So it seems to me that the Session class from Facebook gives you what you want (access to the active session "singleton-style")
HTH

