Подтвердить что ты не робот

Android facebook sdk - Сессия: была сделана попытка повторно авторизовать сеанс, на котором есть ожидающий запрос запрос

В течение последних двух дней я снова ударял головой о facebook-sdk-for-android-wall и нуждался в помощи. Я не могу найти, что неправильно, что я должен сделать вместо этого или как проверить состояние, которое мне не хватает.

Мое приложение для Android записывает дорожки, а для трека пользователь должен выбрать отправку сводки на свою хронику. У меня есть работа как счастливый поток, но при тестировании различных сценариев, таких как отсутствие подключения к Интернету и т.д. Я сейчас застрял в состоянии, когда я получаю только сеанс: попытка была сделана для повторной авторизации сеанса с ожидающим запрос "-exception при попытке повторно авторизовать разрешения (даже при восстановлении интернет-соединения). Я использую SDK для facebook для Android и SSO.

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

Если я отлаживаю SDK для Android, я вижу, что исключение выбрано методом reauthorize в классе Session, потому что pendingRequest не является нулевым, но я не понимаю, почему, где он установлен или как я могу проверить его, удалить его или точить, что я должен делать?

private void reauthorize(ReauthorizeRequest reauthorizeRequest, AuthorizationType authType) {
    validatePermissions(reauthorizeRequest, authType);
    validateLoginBehavior(reauthorizeRequest);
    if (reauthorizeRequest != null) {
        synchronized (this.lock) {
            if (pendingRequest != null) {   //Here 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, но при тестировании я сохранил его в одном методе для удобочитаемости.

4b9b3361

Ответ 1

Вам нужно вызвать метод 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 удаляется.

Ответ 2

Убедитесь, что вы добавили эту строку кода в свою активность.

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data); 
    UiLifecycleHelper.onActivityResult();
} 

Ответ 3

Я запрашиваю у пользователя разрешение на публикацию после входа в систему

Это мой код для 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);
    }

}

Ответ 4

Это происходит, когда предыдущий сеанс не закрыт и не работает правильно, он был только что создан. Поэтому, чтобы избежать этого вопроса. Я обработал его в onResume, когда status isOpend и 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 open/closed.
            Session session = Session.getActiveSession();
            if (session != null && (session.isOpened() || session.isClosed()))
                {
                    onSessionStateChange(session, session.getState(), null);
                }
            else
                {
                    Session.setActiveSession(null);
                }
            uiHelper.onResume();
        }

Ответ 5

Я думаю, что 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);
                }
            }
        };

Ответ 6

Это вполне возможно. Если у вас есть запрос на открытие сеанса facebook до завершения предыдущего запроса, facebook sdk выдает "UnsupportedOperationException". Это может произойти для инициированных пользователем событий, поэтому рекомендуется всегда соответствующим образом обрабатывать это исключение.

PS: В большинстве случаев вам нужно игнорировать это.

Ответ 7

Чтобы предоставить права публикации, прежде чем пользователь захочет что-то публиковать, от определенной активности и без использования "UiLifecycleHelper". Этот метод работал у меня (на основе многих проб и кода в этом конкретном учебнике: https://developers.facebook.com/docs/games/mobile/android-tutorial/ https://developers.facebook.com/docs/facebook-login/permissions/)

Сначала создайте запрос на разрешения (в случае, если у пользователя его нет):

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

Что это.