it-swarm.com.ru

StatusCallback не вызывается после requestNewReadPermissions, затем requestNewPublishPermissions

Я занимаюсь разработкой приложения для Android, которое интегрируется с Facebook. Я бы хотел:

  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;
    }

    /* ... */
}

Поскольку oldState и newState равны (оба являются SessionState.OPENED_TOKEN_UPDATED , мой обратный вызов не вызывается.

Вопрос

Как я могу получить уведомление после получения разрешения во второй раз? Должен ли я close() сеанс и повторно открыть его из кеша ?

Дополнительная информация

Мой Facebook Android SDK 3.0 можно загрузить с здесь , что указано в Facebook Начало работы с Facebook SDK для Android .

22
Pang

Это ошибка.

[править: как Гай отмечает в комментариях, это было исправлено в 3.0.1, поэтому этот обходной путь больше не нужен]

Упомянутый вами обходной путь в основном правильный, хотя вам не нужно звонить близко. Если вы используете один активный сеанс, перед вызовом 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 SDK 3.0, как и в вопросе.

2
Pang

Еще одна вещь, с которой я столкнулся, заключалась в том, что мой requestCode для NewPermissionRequest не был установлен на тот же requestCode, который я использовал для открытия моего Session для чтения, поэтому мой 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));
0
Akos Cz