nuala
nuala

Reputation: 2688

Handling a facebook-object through multiple activities

Currently I'm writing an adapter class to provide a convenient way for communication with the facebook API.
The way I thought about using it is to run the authentication when the app is starting up, downloading user's private picture, and later in the app publishing updates on users facebook wall using an AsyncFacebookRunner.

However flipping through the documentation it seems for every authorize() implementation the first parameter have to be an activity.

void authorize(Activity activity, final DialogListener listener):

And here I begin to wonder.

Thinking about activities and life cycles what will happen when the activity I threw in will be destroyed? Wouldn't the reference for this object Facebook.mAuthActivity become invalid as well.
I see the logout() method "only" asks for a context.

String logout(Context context) throws ...:
context - The Android context in which the logout should be called: it should be the same context in which the login occurred in order to clear any stored cookies

From what I see I can not guarantee the "login-activity" will still be present as app's uptime increases - actually the opposite is more likely.

Are there any special situations I should consider to prevent the app form total crashing in a later state?

Upvotes: 1

Views: 1197

Answers (2)

pzagor2
pzagor2

Reputation: 719

You can try use my FBHelper class.

public class FBHelper {

    private SharedPreferences mPrefs;
    private Context context;
    private final String ACCES_TOKEN = "access_token";
    private final String ACCES_EXPIRES = "access_expires";
    private Facebook facebook;
    private FBHelperCallbacks callback;
    public FBHelper(Context context, Facebook facebook)
    {
        this.context = context;
        this.facebook = facebook;
    }
    public void setSignInFinishListener(FBHelperCallbacks callback)
    {
        this.callback = callback;
    }

    public void FacebookSingleSignIn() {
        mPrefs = ((Activity)context).getPreferences(Context.MODE_PRIVATE);
        String access_token = mPrefs.getString(ACCES_TOKEN, null);
        long expires = mPrefs.getLong(ACCES_EXPIRES, 0);
        if(access_token != null) {
            facebook.setAccessToken(access_token);
        }
        if(expires != 0) {
            facebook.setAccessExpires(expires);
        }
        /*
         * Only call authorize if the access_token has expired.
         */
        if(!facebook.isSessionValid()) {
            Log.i("Facebook","Facebook session is not valid based on acces token... authorizing again");
            facebook.authorize((Activity)context, new String[] {"user_about_me"},new DialogListener() {
                @Override
                public void onFacebookError(FacebookError e) {
                    e.printStackTrace();
                    callback.onError(e.toString());
                }
                @Override
                public void onError(DialogError e) {
                    Log.i("Facebook","onError inner");
                    callback.onError(e.toString());
                }
                @Override
                public void onComplete(Bundle values) {
                    SharedPreferences.Editor editor = mPrefs.edit();
                    editor.putString(ACCES_TOKEN, facebook.getAccessToken());
                    Log.i("Facebook","Saving acces token:"+facebook.getAccessToken());
                    editor.putLong(ACCES_EXPIRES, facebook.getAccessExpires());
                    editor.commit();
                    callback.onSignedInFinished(facebook.getAccessToken());
                }
                @Override
                public void onCancel() {
                    callback.onError("onCancel");
                }
            });
        }
        else
        {
            Log.i("Facebook","Accces token read form preferencesno no need to authorize");
            callback.onSignedInFinished(facebook.getAccessToken());
        }

    }
    public String LogOut()
    {
        try {
            //set ACCES_TOKEN to null 
            mPrefs = ((Activity)context).getPreferences(Context.MODE_PRIVATE);

            SharedPreferences.Editor editor = mPrefs.edit();
            editor.putString(ACCES_TOKEN, null);
            editor.putLong(ACCES_EXPIRES, 0);
            editor.commit();
            return facebook.logout(context);

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "Error";
    }

    public static abstract class FBHelperCallbacks{
        public abstract void onSignedInFinished(String accesToken);
        public abstract void onError(String message);

    }

}

This is how you use this class.

public class LogInActivity extends Activity {
    private static final String TAG = "LogInActivity";
    public static final int REQUEST_CODE = 1;
    private Context context;
    private Facebook facebook;
    private FBHelper fbhelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_log_in);
        this.context = this;

        Handler pauser = new Handler();
        pauser.postDelayed (new Runnable() {
        public void run() {
            facebook = new Facebook(context.getString(R.string.FACEBOOK_APP_ID));
            fbhelper = new FBHelper(context, facebook);
            if (aHelper.isLogedIn())
            {
                //log out
                fbhelper.LogOut();
            }
            else
            {
                //facebook login
                fbhelper.setSignInFinishListener(fbcallback);
                            fbhelper.FacebookSingleSignIn();

            }
            }
        }, 100);
    }

    FBHelperCallbacks fbcallback = new FBHelperCallbacks() {

        @Override
        public void onSignedInFinished(String accesToken) {
            Log.d(TAG,"log in finish");
        }

        @Override
        public void onError(String message) {
            setResult(RESULT_CANCELED);
            finish();

        }
    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        facebook.authorizeCallback(requestCode, resultCode, data);
    }


}

aHelper is object that hold some application specific data. Basically you should decide here if you want to log in or log out.

Upvotes: 1

daigoor
daigoor

Reputation: 685

using facebook API for the android is easy and in your case you don't need to save the Facebook instance the only thing you need is to save the authKey of the facebook on the first login then you can use it anywhere. this means that you can create more than one instance of the facebook object in mutiple activities based on the authKey.

Otherwise you need to put this facebook object in a singleton handler to save it among the application :

class x { 
     private Facebook obj;
     private static x instance;
     private x (){
     }
     public static x getX(){
          if(instance == null){
                instance = new x();
          }
          return instance;
     }

     public void setIt(Facebook obj){
          this.obj = obj;
     }
     public Facebook getIt(){
           return obj;
     }
}

but this way is not the best way to implement the code you need to create a Facebook instance for each activity using the authKy.

Upvotes: 0

Related Questions