web-dev-qa-db-ja.com

requestNewReadPermissions、requestNewPublishPermissionsの後にStatusCallbackが呼び出されない

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));
_

今回は、許可が与えられた後、私のコールバックはnot呼び出されます。

調査

さらに調査したところ、コールバックは 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_ なので、私のコールバックは呼び出されません。

質問

2回目の許可が与えられた後、どのように通知を受け取ることができますか?セッションを close() して、 キャッシュから再度開く ことになっていますか?

追加情報

私のFacebook Android SDK 3.0は here からダウンロードされます。これはFacebookの Getting Started with the Facebook SDKforに記載されています。アンドロイド

22
Pang

これはバグです。

[編集:Guyがコメントで指摘しているように、これは3.0.1で修正されたため、この回避策は不要になりました]

あなたが言及する回避策は基本的に正しいですが、closeを呼び出す必要はありません。単一のアクティブなセッションを使用している場合は、requestNewPublishPermissions()を呼び出す前に、次のコマンドを呼び出すだけです。

Session.openActiveSessionFromCache(myContext);

複数のセッションを使用している場合は、TokenCachingStrategyを使用して新しいセッションを初期化し、それがCREATED_TOKEN_LOADED状態にあることを確認して、openForRead(null);を呼び出す必要があります。

これらのいずれかを実行した後、requestNewPublishPermissions()は、通知が完了したら通知を呼び出す必要があります。

10
rightparen

rightparenの答え に基づく作業コード

2回目の許可を要求する前に(つまり、 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 SDK3.0に基づいています。

2
Pang

私が遭遇したもう1つのことは、NewPermissionRequestのrequestCodeが、ReadwithのSessionを開くために使用したのと同じ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を作成するときに同じrequestCodeを使用するのを忘れました。

これは正しいNewPermissionRequestがどのように見える必要があるかです:

        Session.getActiveSession().requestNewPublishPermissions(
            new NewPermissionsRequest(activity, MY_PUBLISH_PERMISSIONS)
                .setRequestCode(FACEBOOK_AUTH_RESULT_CODE));
0
Akos Cz