StatusCallback не вызывается после запросаNewReadPermissions, а затем requestNewPublishPermissions
Я разрабатываю приложение для Android, которое интегрируется с Facebook. Я бы хотел:
- Позвольте пользователю войти в Facebook
- Получить адрес электронной почты пользователя на Facebook (может быть проксированный адрес электронной почты, что хорошо)
- Опубликовать на стене пользователя/временной шкале от его имени
Технически это будет:
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);
Мой обратный вызов вызывается после успешного входа в систему. Пока все хорошо.
Это мой статус-ответ:
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));
Мой callback вызывается после разрешения. Пока все хорошо.
Это мой статус-ответ:
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;
}
/* ... */
}
Так как oldState
и newState
равны (оба являются SessionState.OPENED_TOKEN_UPDATED
, мой обратный вызов не вызывается.
Вопрос
Как я могу получать уведомления после получения разрешения на второй раз? Предполагаю ли я close()
сеанс и повторно открыть его из кеша?
Дополнительная информация
Мой Android Android SDK 3.0 загружается из здесь, о чем говорится в Facebook Начало работы с SDK для Android для Android.
Ответы
Ответ 1
Это ошибка.
[edit: Как указывает Гай в комментариях, это было исправлено в 3.0.1, поэтому это обходное решение больше не требуется]
Обходной путь, который вы упоминаете, в основном правильный, хотя вам не нужно звонить близко. Если вы используете один активный сеанс, перед вызовом requestNewPublishPermissions() просто вызовите:
Session.openActiveSessionFromCache(myContext);
Если вы используете несколько сеансов, вам нужно инициализировать новый сеанс с помощью TokenCachingStrategy, проверить, что он находится в состоянии CREATED_TOKEN_LOADED, и вызвать openForRead (null);
После выполнения одного из них requestNewPublishPermissions() должен вызывать ваше уведомление после его завершения.
Ответ 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, как в вопросе.
Ответ 3
Еще одна вещь, с которой я столкнулся, заключалась в том, что мой requestCode для NewPermissionRequest
не был настроен на тот же код запроса, который я использовал для открытия моего 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));
Затем я забыл использовать тот же requestCode при построении моего NewPermissionRequest
.
Вот что должно выглядеть правильно NewPermissionRequest
:
Session.getActiveSession().requestNewPublishPermissions(
new NewPermissionsRequest(activity, MY_PUBLISH_PERMISSIONS)
.setRequestCode(FACEBOOK_AUTH_RESULT_CODE));