22

我正在开发一个与 Facebook 集成的 Android 应用程序。我想:

  1. 让用户使用 Facebook 登录
  2. 在 Facebook 上获取用户的电子邮件地址(可以是代理的电子邮件地址,这很好)
  3. 代表他/她发布到用户的墙上/时间线

从技术上讲,这将是:

  1. 验证用户
  2. 请求email许可
  3. 请求publish_stream许可

1. 对用户进行身份验证

我打Session.openActiveSession()了电话Session.StatusCallback(我已经事先检查过没有活动的打开会话):

final Session.StatusCallback sessionStatusCallback = new Session.StatusCallback() {
    public void call(final Session session, SessionState state, Exception exception) {
        // If there is an exception...
        if(exception != null)
        {
            // Handle fail case here.
            return;
        }

        // If session is just opened...
        if(state == SessionState.OPENED)
        {
            // Handle success case here.
            return;
        }
    };
};

// Start Facebook Login.
Session.openActiveSession(activity, true, sessionStatusCallback);

成功登录后调用我的回调。到现在为止还挺好。

2.请求email许可

这是我的状态回调:

new Session.StatusCallback() {
    public void call(final Session session, SessionState state, Exception exception) {
        // If there is an exception...
        if(exception != null)
        {
            // Handle fail case here.
            return;
        }
        
        // If token is just updated...
        if(state == SessionState.OPENED_TOKEN_UPDATED)
        {
            // Handle success case here.
            return;
        }
    };
};

我请求许可Session.requestNewReadPermissions()

final Session session = Session.getActiveSession();
final static String[] PERMISSION_ARRAY_READ = {"email"};
final List<String> permissionList = Arrays.asList(PERMISSION_ARRAY_READ);

// If all required permissions are available...
if(session.getPermissions().containsAll(permissionList))
{
    // Handle success case here.
    return;
}

// Request permissions.
session.requestNewReadPermissions(new Session.NewPermissionsRequest(activity, permissionList));

授予权限后调用我的回调。到现在为止还挺好。

3.请求publish_stream许可

这是我的状态回调:

new Session.StatusCallback() {
    public void call(final Session session, SessionState state, Exception exception) {
        // If there is an exception...
        if(exception != null)
        {
            // Handle fail case here.
            return;
        }
        
        // If token is just updated...
        if(state == SessionState.OPENED_TOKEN_UPDATED)
        {
            // Handle success case here.
            return;
        }
    };
};

我请求许可Session.requestNewPublishPermissions()

final Session session = Session.getActiveSession();
final static String[] PERMISSION_ARRAY_PUBLISH = {"publish_stream"};
final List<String> permissionList = Arrays.asList(PERMISSION_ARRAY_PUBLISH);

// If all required permissions are available...
if(session.getPermissions().containsAll(permissionList))
{
    // Handle success case here.
    return;
}

// Request permissions.
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(activity, permissionList));

这一次,我的回调在被授予权限后没有被调用。

调查

经过进一步调查,我发现我的回调是由以下触发的com.facebook.Session#postStateChange(SessionState, SessionState, Exception)

void postStateChange(final SessionState oldState, final SessionState newState, final Exception exception) {
    if (oldState == newState && exception == null) {
        return;
    }

    /* ... */
}

因为oldStatenewState相等(两者都是SessionState.OPENED_TOKEN_UPDATED,所以我的回调没有被调用。

问题

第二次获得许可后如何收到通知?我应该进行close()会话并从缓存中重新打开它吗?

附加信息

我的 Facebook Android SDK 3.0 是从这里下载的,这在 Facebook 的Android 版 Facebook SDK 入门中有说明

4

3 回答 3

10

这是一个错误。

[编辑:正如盖伊在评论中指出的那样,这已在 3.0.1 中修复,因此不再需要此解决方法]

您提到的解决方法基本上是正确的,尽管您不需要调用 close。如果您使用的是单个活动会话,则在调用 requestNewPublishPermissions() 之前只需调用:

Session.openActiveSessionFromCache(myContext);

如果使用多个会话,则需要使用 TokenCachingStrategy 初始化一个新的 Session,验证它是否处于 CREATED_TOKEN_LOADED 状态,然后调用 openForRead(null);

完成其中一项后, requestNewPublishPermissions() 应该在完成后调用您的通知。

于 2012-12-26T22:15:39.173 回答
2

基于rightparen答案的工作代码

在第二次(即之前Session.requestNewPublishPermissions())请求许可之前,请执行以下操作:

// Re-initialize Facebook session.
session.removeCallback(sessionStatusCallback);          // Remove callback from old session.
session = Session.openActiveSessionFromCache(context);  // Create new session by re-opening from cache.
session.addCallback(sessionStatusCallback);             // Add callback to new session.

如问题所示,代码仍然基于 Facebook Android SDK 3.0。

于 2013-01-16T02:28:53.313 回答
0

我遇到的另一件事是我的 requestCodeNewPermissionRequest没有被设置为我用来打开我Session的 for Read 的相同 requestCode,因此Session.StatusCallback在授予新权限时我从未被调用。

例如,在我onActivityResult的检查中,我检查了 requestCode 并相应地委派了调用,因为我有其他东西进入这个方法。

public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
    if (requestCode == FACEBOOK_AUTH_RESULT_CODE) {
        Session session = Session.getActiveSession();
        if(session != null) {
            session.onActivityResult(activity, requestCode, resultCode, data);
        }
    }       
}

然后我Session用以下代码打开了我的:

        Session.getActiveSession().openForRead(
            new Session.OpenRequest(activity).
                setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK).
                setRequestCode(FACEBOOK_AUTH_RESULT_CODE).
                setPermissions(MY_READ_PERMISSIONS));

然后我在构建我的NewPermissionRequest.

这就是正确NewPermissionRequest的样子:

        Session.getActiveSession().requestNewPublishPermissions(
            new NewPermissionsRequest(activity, MY_PUBLISH_PERMISSIONS)
                .setRequestCode(FACEBOOK_AUTH_RESULT_CODE));
于 2013-07-26T20:52:39.857 回答