Search code examples
androidandroid-fragmentsactionbarsherlockfacebook-android-sdkfragmentpageradapter

Why doesn't Android Facebook interface work with Fragments?


I'm switching some Android Facebook code from an Activity to a Fragment. Prior to the switch everything worked fine, but now the onComplete() callback is not being executed.

Does the Facebook code not work with Fragments, or am I doing something wrong?

Here's the original code (in a SherlockActivity):

if (!mFacebook.isSessionValid()) {
    mFacebook.authorize(MyActivity.this, permissions, new DialogListener() {
        @Override
        public void onComplete(Bundle values) { ... }    // CALLED AS EXPECTED
    }
}

And here's the new code (in a SherlockFragment):

if (!mFacebook.isSessionValid()) {
    mFacebook.authorize(getActivity(), permissions, new DialogListener() {
        @Override
        public void onComplete(Bundle values) { ... }    // DOES NOT GET CALLED
    }
}

Both the Activity and the Fragment include the same onActivityResult() as required by Facebook:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    mFacebook.authorizeCallback(requestCode, resultCode, data);
}

Thanks for your help!

EDIT: A similar question is asked here, where the accepted answer is to change the Fragment to a FragmentActivity. But I don't see how this helps, as then it's no longer a Fragment (which I need for other reasons). Suggestions?

EDIT 2: I rolled my own solution. See below.


Solution

  • As far as I could determine, the Facebook auth API does not support Fragments. Specifically, the onComplete() callback from the Facebook authorize() call works with Activities, but not with Fragments.

    So I put together a simple workaround for Fragments. The solution depends on the fact that onActivityResult() is also called in the parent Activity when the authorize() call completes, so you can use it to set up a separate callback mechanism for the Fragment.

    First, set up a variable in the parent Activity to carry the target Fragment's name, say

    TargetFragment mTargetFragment;
    

    You can initialize it when the Fragment is first instantiated like this:

    @Override
    public void onAttachFragment(Fragment fragment) {
        super.onAttachFragment(fragment);
    
        String fragmentSimpleName = fragment.getClass().getSimpleName();
    
        if (fragmentSimpleName.equals("TargetFragment"))
            mTargetFragment = (TargetFragment)fragment;        
    }
    

    Then add a couple of lines to the onActivityResult() function:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    
        if (mTargetFragment != null)       
            mTargetFragment.myCallBack(requestCode, resultCode, data);
    }
    

    Now you can just mimic the code you would ordinarily put in the onComplete() callback in the new myCallBack() function:

    public void myCallBack(int requestCode, int resultCode, Intent data) {
        mFacebook.authorizeCallback(requestCode, resultCode, data);
    
        // other code from your onComplete() function ...
    }
    

    I hope this can help someone else. Cheers!