【问题标题】:Facebook publish permission - posting from serverFacebook 发布权限 - 从服务器发布
【发布时间】:2014-02-11 15:18:37
【问题描述】:

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

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

这就是我为发布许可所做的事情

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)如何在发布权限被批准后立即获得刷新的accessToken? 2)如果(1)不可能,那么正确的做法是什么?因为来自客户的电话必须与 更新访问令牌。是否让用户等到我们获得更新的 accessToken?如果是怎么办?

谢谢。

【问题讨论】:

  • 我终于想通了。完成测试后,我将发布完整的解决方案。

标签: android facebook permissions


【解决方案1】:

回答我自己的问题

花了好几个小时才弄明白。这里分步询问读取和发布权限的过程

设置 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 在您的 Fragment 和主 Activity 中都存在。并调用 Session.onActivityResult

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

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

有趣的是,FB SDK 仅在您请求发布许可时才会显示此内容。在内部,FB sdk 通过“me”调用与之前的(现有会话 fbid)比较响应(返回可能为 null)来验证 fbid,如果这两个 SDK 之间存在差异,则会显示此错误。

如何避免这种情况? -- 确保您已正确设置您的 FB 应用程序,特别是包名称。 ——这让我发疯了。不要使用代理。在以某种方式使用代理 android 手机时,FB SDK 的内部“ME”调用以验证 FBID 失败,并出现错误 com.facebook.FacebookException: could not construction request body and graph user become null,因此出现此错误。虽然有点奇怪,因为我使用的是普通拦截代理的提琴手

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-23
    • 2015-08-19
    • 1970-01-01
    相关资源
    最近更新 更多