20

在过去的几天里,我一直在用 facebook-sdk-for-android-wall 敲打我的头,需要帮助。我找不到问题所在,我应该做什么,或者如何检查我缺少的某些状态。

我的 Android 应用程序正在录制曲目,对于曲目,用户必须选择将曲目摘要发布到他/她的 Facebook 时间线。我已经让它像一个快乐的流程一样工作,但是在测试不同的场景(例如没有互联网连接等)时,我现在陷入了一种状态,我只能得到“会话:尝试重新授权具有待处理请求的会话" - 尝试重新授权权限时出现异常(即使互联网连接已恢复)。我正在使用适用于 android 和 SSO 的 facebook SDK。

package com.test;

import java.io.Fil...
...

public class FaceBookUtil {

public interface FacebookPostCallback {
    void onComplete(String postId);
    void onError(Exception e);
    void onError();
}

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

public static void postToFaceBook(final Track track, final Activity activity, final FacebookPostCallback postCallback) {

    try {
        Session session = initFacebookSession(activity.getApplicationContext());
        Session.setActiveSession(session);

        StatusCallback statusCallback = new StatusCallback() {
            @Override
            public void call(Session session, SessionState state, Exception exception) {

                try {
                    // Check for publish permissions    
                    List<String> permissions = session.getPermissions();
                    if (!isSubsetOf(PERMISSIONS, permissions)) {
                        Session.ReauthorizeRequest reauthRequest = new Session
                                .ReauthorizeRequest(activity, PERMISSIONS)
                                .setRequestCode(REAUTH_ACTIVITY_CODE);
                        session.reauthorizeForPublish(reauthRequest);    //Here's where it breaks and the exceptions is thrown.
                        return;
                    }

                    Bundle postParams = new Bundle();
                    postParams.putString("name", "Facebook post test"); 
                    postParams.putString("caption", "Just a test"); 
                    postParams.putString("description", "A description");
                    postParams.putString("link", "http://www.google.com/");

                    Request.Callback reqCallback = new Request.Callback() {
                        public void onCompleted(Response response) {
                            String postId = null;

                            try {
                                FacebookException error = response.getError();
                                if (error != null)
                                    throw error;

                                JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();

                                postId = graphResponse.getString("id");
                                if (postId != null)
                                    postCallback.onComplete(postId);

                            } catch (Exception e) {
                                postCallback.onError();
                            }

                            if (postId == null)
                                postCallback.onError();
                        }
                    };

                    Request postRequest = new Request(session, "me/feed", postParams, HttpMethod.POST, reqCallback);
                    RequestAsyncTask task = new RequestAsyncTask(postRequest);
                    task.execute();

                } catch (Exception e) {
                    postCallback.onError(e);
                }
            }
        };

        if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED))
            session.openForRead(new Session.OpenRequest(activity).setCallback(statusCallback));

        else if (!session.isOpened() && !session.isClosed()) {
            OpenRequest req = new Session.OpenRequest(activity);
            req.setCallback(statusCallback);
            session.openForRead(req);

        } else {
            Session.openActiveSession(activity, true, statusCallback);

        }

    } catch (Exception e) {
        postCallback.onError(e);
    }    
}

private static boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
    for (String string : subset) {
        if (!superset.contains(string)) {
            return false;
        }
    }
    return true;
}

private static Session initFacebookSession(Context context) {

    Session session = Session.getActiveSession();

    if (session != null) 
        return session;

    /*
    if (savedInstanceState != null)
        session = Session.restoreSession(this, null, sessionStatusCallback, savedInstanceState);
    */

    if (session == null)
        session = new Session(context);

    return session;
}
}

如果我调试到 android SDK,我可以看到异常是由 Session 类中的 reauthorize 方法引发的,因为 pendingRequest 不为空,但我不明白为什么,它在哪里设置或如何检查它,删除它或者我应该做什么?

private void reauthorize(ReauthorizeRequest reauthorizeRequest, AuthorizationType authType) {
    validatePermissions(reauthorizeRequest, authType);
    validateLoginBehavior(reauthorizeRequest);
    if (reauthorizeRequest != null) {
        synchronized (this.lock) {
            if (pendingRequest != null) {   //Here's where the pendingRequest is already set and causes the exception...
                throw new UnsupportedOperationException(
                        "Session: an attempt was made to reauthorize a session that has a pending request.");
            }
            switch (this.state) {
                case OPENED:
                case OPENED_TOKEN_UPDATED:
                    pendingRequest = reauthorizeRequest;
                    break;
                default:
                    throw new UnsupportedOperationException(
                            "Session: an attempt was made to reauthorize a session that is not currently open.");
            }
        }

        authorize(reauthorizeRequest);
    }
}

我已经在没有任何结果的情况下搜索了异常,非常感谢任何帮助。

附带说明一下,我可能可以重构整个 FacebookUtil.postToFaceBook 方法,但在测试时我将其保留在一种方法中以提高可读性。

4

7 回答 7

8

在请求更多权限时,您需要在当前 Session 上调用 onActivityResult() 方法:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Logger.d(LOGTAG, "onActivityResult");
    if (RESULT_CANCELED == resultCode) {
        mAuthorizationCanceled = true;
    }
    **mFacebookSession.onActivityResult(this, requestCode, resultCode, data);**
}

这样,再次调用 StatusCallback 并删除 pendingRequest。

于 2013-01-17T12:55:34.090 回答
5

检查以确保您在 Activity 中添加了这行代码。

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data); 
    UiLifecycleHelper.onActivityResult();
} 
于 2012-11-07T21:42:13.293 回答
2

我在登录后请求用户发布权限

这是我的 SDK V3.0.1 代码

public class FacebookAccount extends FragmentActivity {
    private UserSettingsFragment userSettingsFragment;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.facebook_login);

        FragmentManager fragmentManager = getSupportFragmentManager();
        userSettingsFragment = (UserSettingsFragment) fragmentManager
                .findFragmentById(R.id.login_fragment);

        userSettingsFragment.setReadPermissions(Utility.READ_PERMISSIONS);

        userSettingsFragment
                .setSessionStatusCallback(new Session.StatusCallback() {
                    @Override
                    public void call(Session session, SessionState state,
                            Exception exception) {
                        if (state == SessionState.OPENED
                                && !session.getPermissions().containsAll(
                                        Utility.PUBLISH_PERMISSIONS)) {
                            session.requestNewPublishPermissions(new Session.NewPermissionsRequest(
                                    FacebookAccount.this,
                                    Utility.PUBLISH_PERMISSIONS));
                        }
                        if (session.isOpened()
                                && state == SessionState.OPENED_TOKEN_UPDATED) {
                            //Save session access token
                        }
                    }
                });
    }

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

}
于 2013-06-22T02:26:49.720 回答
1

它发生在上一个会话未关闭且未正确打开时,它刚刚创建所以为了避免这种情况,我在 onResume 中处理它,当状态为 notOpend 和 notClosed 然后 setActive session null。它为我工作

public void onResume()
        {
            super.onResume();
            is not null, the session state change notification
            // may not be triggered. Trigger it if it's open/closed.
            Session session = Session.getActiveSession();
            if (session != null && (session.isOpened() || session.isClosed()))
                {
                    onSessionStateChange(session, session.getState(), null);
                }
            else
                {
                    Session.setActiveSession(null);
                }
            uiHelper.onResume();
        }
于 2014-10-12T07:05:05.013 回答
0

为了在用户真正想要从某个活动发布某些内容之前授予发布权限,并且不使用“UiLifecycleHelper”。这种方法对我有用(基于许多试验和这个特定教程中的代码: https ://developers.facebook.com/docs/games/mobile/android-tutorial/ https://developers.facebook.com/docs/ facebook-登录/权限/

首先创建权限请求(以防用户没有权限):

Session session = Session.getActiveSession();
if (PostOnFB.isChecked() && session != null && session.isOpened()) {
    List<String> permissions = session.getPermissions();
    if (!permissions.contains("publish_actions")) {
        // if they choose to publish, then we request for publish permissions
        Session.NewPermissionsRequest newPermissionsRequest =
                new Session.NewPermissionsRequest(GetUserLocationActivity.this, Arrays.asList("publish_actions"))
                        .setDefaultAudience(SessionDefaultAudience.FRIENDS)
                        .setCallback(newPermissionsCallback)
                        .setRequestCode(REAUTH_ACTIVITY_CODE);
        session.requestNewPublishPermissions(newPermissionsRequest);
    } else {
        publishResult();
    }
}

其中“publishResult()”是用户获得权限后调用的方法。

接下来,为 onActivityResult 添加一个案例:

@Override
public void onActivityResult (
        int requestCode, int resultCode, Intent data) {
    // Decide what to do based on the original request code
    switch (requestCode) {
        case ..
        ..
        ..
        ..
        ..
        case REAUTH_ACTIVITY_CODE :
        Session.getActiveSession().onActivityResult(GetUserLocationActivity.this, requestCode, resultCode, data);
    }
 }

最后实现回调:

private Session.StatusCallback newPermissionsCallback = new Session.StatusCallback() {
    @Override
    public void call(Session session, SessionState state, Exception exception) {
        if (exception != null || !session.isOpened() || !session.getPermissions().contains("publish_actions")) {
            // this means the user did not grant us write permissions, so
            // do whatever you think
        } else {
            publishResult();
        }
    }
};

而已。

于 2014-04-09T14:58:00.440 回答
0

这是很有可能的,如果您在完成之前的请求之前请求打开 facebook 会话,facebook sdk 将抛出“UnsupportedOperationException”。这可能发生在用户启动的事件中,因此始终建议适当地处理该异常。

PS:在大多数情况下,您需要忽略这一点。

于 2013-03-04T08:32:18.600 回答
0

我猜 Facebook 只是不允许两个打开请求一起运行。

如果您只需要打开具有发布权限的会话(而不是在读取和发布之间切换),那么有一种简单的方法可以做到这一点。

转到Sessions.java源代码并将此功能更改private static Session openActiveSession(Context context, boolean allowLoginUI, OpenRequest openRequest)public.

使用它登录 Facebook:

private void loginFacebook() {  
        Session session = Session.getActiveSession();
        if (session == null) {
            session = new Session(this);
        }
        Session.setActiveSession(session);

        Session.OpenRequest request = new Session.OpenRequest(this).setCallback(statusCallback);
        request.setPermissions(Arrays.asList(publishPermissions));
        if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
            session.openForPublish(request);
        } else {
            session = Session.openActiveSession(this, true, request);
        }
    }

并使用它来发布:

StatusCallback statusCallback = new StatusCallback() {
            @Override
            public void call(Session session, SessionState state, Exception exception) {

                try {

                    Bundle postParams = new Bundle();
                    postParams.putString("name", "Facebook post test"); 
                    postParams.putString("caption", "Just a test"); 
                    postParams.putString("description", "A description");
                    postParams.putString("link", "http://www.google.com/");

                    Request.Callback reqCallback = new Request.Callback() {
                        public void onCompleted(Response response) {
                            String postId = null;

                            try {
                                FacebookException error = response.getError();
                                if (error != null)
                                    throw error;

                                JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();

                                postId = graphResponse.getString("id");
                                if (postId != null)
                                    postCallback.onComplete(postId);

                            } catch (Exception e) {
                                postCallback.onError();
                            }

                            if (postId == null)
                                postCallback.onError();
                        }
                    };

                    Request postRequest = new Request(session, "me/feed", postParams, HttpMethod.POST, reqCallback);
                    RequestAsyncTask task = new RequestAsyncTask(postRequest);
                    task.execute();

                } catch (Exception e) {
                    postCallback.onError(e);
                }
            }
        };
于 2012-11-08T10:08:55.577 回答