Facebook发布权限 - 从服务器发布

时间:2014-02-11 15:18:38

标签: android facebook permissions

在我的应用中,我首先询问用户第一个基本权限,并在需要时发布。客户端本身不会对accessToken做任何事情,只是将它传递给服务器。

1)获得基本权限后,客户端立即将其发送到服务器。 2)当客户端请求发布权限时问题开始。用户授予发布权限后,我的会话仍会显示旧的基本权限。但是,如果我同时检查fb上的用户设置,则表明应用已授予发布权限。但不知何故在应用程序中我没有得到  更新了accessToken。

这就是我为发布权限所做的事情

private void requestPublishPermissions(Session session) {
    if (session != null) {
        Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(this, PERMISSION)
                // demonstrate how to set an audience for the publish permissions,
                // if none are set, this defaults to FRIENDS
                .setDefaultAudience(SessionDefaultAudience.FRIENDS)
                .setRequestCode(REAUTH_ACTIVITY_CODE);
        session.requestNewPublishPermissions(newPermissionsRequest);
    }
}

一旦用户授予权限(当调用此方法时),此方法调用之后的下一个Session.StatusCallback仍会显示旧的会话权限。

我的问题: 1)如何在发布permisison批准后立即刷新accessToken? 2)如果(1)不可能,那么正确的做法是什么?因为来自客户的电话必须与 更新了accessToken。是否让用户等到我们获得更新的accessToken?如果是的如何?

感谢。

1 个答案:

答案 0 :(得分:2)

回答我自己的问题

花了几个小时后想出来了。这里一步一步询问读取和发布权限

设置 Eclipse,Android,Facebook SDK 3.6 计划 MainActivity和静态片段 尝试实现?请求读取权限然后发布权限。

MainActivity

public class YourFragmentActivity extends FragmentActivity {

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //Static Fragment
    setContentView(R.layout.fragment_layout);
}


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
}

YourFragment.java

public class YourFragment extends Fragment {
public static String TAG = YourFragment.class.getSimpleName();

private static final List<String> PERMISSIONS = Arrays.asList("publish_stream, publish_actions");

// Flag to represent if we are waiting for extended permissions

private Session.StatusCallback statusCallback = new SessionStatusCallback();
private Session.StatusCallback publishCallback = new PublishCallback();

private Button publish;



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

    buttonLoginLogout = (Button) view.findViewById(R.id.buttonLoginLogout);
    publish = (Button) view.findViewById(R.id.publish);


            //Make Sure you have session when you instantiate fragment
    Session session = Session.getActiveSession();
    if (session == null) {
        if (savedInstanceState != null) {
            session = Session.restoreSession(getActivity(), null, statusCallback, savedInstanceState);
        }
        if (session == null) {
            session = new Session(getActivity());
        }
        Session.setActiveSession(session);
        if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
            session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
        }
    }

    onSessionStateChange();

    return view;
}

@Override
public void onStart() {
    super.onStart();
    Session.getActiveSession().addCallback(statusCallback);
}

@Override
public void onStop() {
    super.onStop();
    Session.getActiveSession().removeCallback(statusCallback);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Session.getActiveSession().onActivityResult(getActivity(), requestCode, resultCode, data);
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Session session = Session.getActiveSession();
    Session.saveSession(session, outState);
}

private void onSessionStateChange() {
    Session session = Session.getActiveSession();

    if(session.getPermissions().contains("publish_actions")){

                 //You got you updated token here with extended permissions
    }
    if (session.isOpened()) {

                 //Do you stuff here. e.g Getting accessToken, expiry etc.

    }
    else {
    }
}

public  void requestPublishPermissions(Activity activity, Session session, List<String> permissions, int requestCode) {

    if (session != null) {
        Session.NewPermissionsRequest reauthRequest = new Session.NewPermissionsRequest(activity, permissions).setRequestCode(requestCode);
        reauthRequest.setCallback(publishCallback);

        session.requestNewPublishPermissions(reauthRequest);
    }
}

    //Set this on onclick call of some button in you fragment
private void openForRead() {
    Session session = Session.getActiveSession();
    if (!session.isOpened() && !session.isClosed()) {
        session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
    }
    else {
        Session.openActiveSession(getActivity(), this, true, statusCallback);
    }
}

    //Set this on onclick call of some logout button in you fragment 
private void logMeOut() {
    Session session = Session.getActiveSession();
    if (!session.isClosed()) {
        session.closeAndClearTokenInformation();
    }
}

private class SessionStatusCallback implements Session.StatusCallback {
    @Override
    public void call(Session session, SessionState state, Exception exception) {
        onSessionStateChange();
        Debug.waitForDebugger();
        if (exception != null){
                            //Handel your exception case here 
            Log.i(TAG, exception.getMessage());
                    }
    }
}

private class PublishCallback implements Session.StatusCallback {
    @Override
    public void call(Session session, SessionState state, Exception exception) {
        Debug.waitForDebugger();
        onSessionStateChange();
        if (exception != null){
                            //Handel your exception case here
            Log.i(TAG, exception.getMessage());
                     }
    }
}
}

您可能遇到的错误

  • 1)发布权限永不回电

这是最烦人的一个。当用户授予发布权限时,回调永远不会返回但是相同 如果您的用户在FB中看到其应用设置页面,则表明用户已授予发布权限 给你的应用程序。在这种情况下,从技术上讲,我们可以使用我们在readForOpen调用中收到的相同accessToken,因为大多数时候accessToken即使在成功回调之后也不会改变(这不是一个缺陷)。但我们不能依赖于此,因为FB可以随时更改accessToken。

如何避免这种情况? - 确保片段和主要活动中都有onActivityResult。并调用Session.onActivityResult

- 确保您要为newRequest设置发布回调。 FB使用addCallback(newPermissionsRequest.getCallback())从NewPermissionsRequest返回回调实例;

  • 2)用户以不同的Facebook用户身份登录

有趣的是,只有当您要求发布权限时,FB SDK才会显示此信息。内部FB sdk通过使用“my”调用比较响应(返回可以为null)与之前的(现有会话fbid)之一来验证fbid,如果这两个SDK之间存在差异则显示此错误。

如何避免这种情况? - 确保您已正确设置FB应用程序包名称。 - 这个让我疯了。不要使用代理。而使用代理Android手机不知何故FB SDK的内部“ME”调用验证FBID失败,错误com.facebook.FacebookException:无法构造请求体和图形用户变为null,因此这个错误。虽然是有点奇怪,因为我使用的是正常拦截代理的小提琴手

我希望这会有所帮助。