FB sdk, requestNewPublishPermissions() doesn't

2019-05-30 16:35发布

问题:

I followed the FB tutorial step by step, and I can't figure out why is this not working.

All my fragments inherits from the BaseFragment :

public class BaseFragment extends SherlockFragment {
    ...
    protected UiLifecycleHelper _uiHelper;
    protected boolean _isResumed = false;

    protected static final List<String> PERMISSIONS = Arrays.asList("publish_actions");
    protected static final String PENDING_PUBLISH_KEY = "pendingPublishReauthorization";
    protected boolean _pendingPublishReauthorization = false;


    protected Session.StatusCallback _callback = new Session.StatusCallback() {
        @Override
        public void call(Session session, SessionState state, Exception exception) {
            onSessionStateChange(session, state, exception);
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        _uiHelper = new UiLifecycleHelper(getSherlockActivity(), _callback);
        _uiHelper.onCreate(savedInstanceState);
    }

    protected void onSessionStateChange(Session session, SessionState state, Exception exception) {}

    ...(all lifecycle stuff)
}

Then I have a FacebookLoginFragment which contains the login/logout button :

public class FacebookLoginFragment extends BaseFragment {

    protected LoginButton _authButton;
    protected ProgressBar _loadingBar;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.facebook_login, container, false);

        _loadingBar = (ProgressBar) view.findViewById(R.id.login_progressBar);

        _authButton = (LoginButton) view.findViewById(R.id.authFacebookButton);
        _authButton.setFragment(this);
        _authButton.setReadPermissions(Arrays.asList("email", "user_birthday"));

        return view;
    }

    @Override
    protected void onSessionStateChange(Session session, SessionState state, Exception exception) {
        super.onSessionStateChange(session, state, exception);

        // LogIn process
    }
    ...
}

And finally I've a NewsFragment which contains a listView of feeds. Each feed is sharable. When we click on the share button of a feed, the adapter call the NewsFragment.publishFeed(feed) method.

public class NewsFragment extends BaseFragment{
    ...
    protected Feed _feedPendingPublish;

    @Override
    // => NEVER CALLED 
    protected void onSessionStateChange(Session session, SessionState state, Exception exception) {
        super.onSessionStateChange(session, state, exception);

        if (_isResumed) {

            if (_pendingPublishReauthorization && state.equals(SessionState.OPENED_TOKEN_UPDATED)) {
                _pendingPublishReauthorization = false;
                if(_feedPendingPublish != null){
                    publishFeed(_feedPendingPublish);
                    _feedPendingPublish = null;
                }
            }
        }
    }

    public void publishFeed(Feed feed){

        if(_pendingPublishReauthorization){
            return;
        }

        Session session = Session.getActiveSession();

        if (session != null){

            // If permission doesn't exist, ask and return. Otherwise, send request

            List<String> permissions = session.getPermissions();
            if (!isSubsetOf(PERMISSIONS, permissions)) {
                _pendingPublishReauthorization = true;
                _feedPendingPublish = feed;

                Session.NewPermissionsRequest newPermissionsRequest = new Session
                    .NewPermissionsRequest(getSherlockActivity(), PERMISSIONS);
                session.requestNewPublishPermissions(newPermissionsRequest);

                return;
            }

            // DO stuff
        }
    }
}

The problem is that the NewsFragment callback is not called after the publish authorization. (neither the BaseFragment, neither the FacebookLogin). Note that both fragments exist in the same activity.

I'm using facebook-android-sdk-3.5.2

回答1:

I finally figured this out. As many people said, it was an onActivityResult() problem, but quite vicious.

When Log In, the FacebookLoginFragment.onSessionStateChange() was called succefully, whereas the NewsFragment.onSessionStateChange() was never called during the persmission process.

After several tests, I assume this was due to a static and dynamic binding. My FacebookLoginfragment is directy referenced in the xml (static), whereas my NewsFragment is added dynamically in the source code. Consequently, the Activity which contains both fragments was only sending the onActivityResult signal to the FacebokLoginFragment. Therefore, the NewsFragment.onActivityResult() which is necessary to trigger the callback was never called.

Overriding the Activity.onActivityResult() gives me the expected behavior :

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    getSupportFragmentManager().findFragmentById(R.id.my_fragment_frame).onActivityResult(requestCode, resultCode, data);
} 


回答2:

Yes, there indeed seems to still be a bug around callbacks and new permissions requests.

As a temporary work around, you can call:

session.addCallback(yourCallback);

just before you call session.requestNewPublishPermissions.

Note that this callback will now receive all future state changes on your session. If that's not what you want, you can always call session.removeCallback(yourCallback) after you do the publish.



回答3:

Even if you add the callback as Ming said, you may have an issue.

See this bug: https://developers.facebook.com/bugs/130681460449340

It looks like there is a proposed solution/workaround in the comments.