Создайте объект сеанса Facebook, используя токен доступа на Android

Я пытаюсь сделать следующее:

  1. На одном мобильном устройстве Android я авторизую свое приложение с помощью Facebook и сохраняю токен доступа в общих настройках.
  2. Отправка этого токена доступа на второе устройство Android (с другим приложением, имеющим тот же appKey для Facebook.
  3. Теперь я не могу создать сеанс, используя этот токен доступа на втором устройстве. На втором устройстве нет пользовательского интерфейса, поэтому я не могу использовать собственное веб-приложение/FB для авторизации там.

Вопрос: Мой вопрос заключается в том, как я могу создать сеанс facebook для доступа к API, используя этот переданный токен доступа. Будет полезнее, если кто-нибудь укажет на пример.


person Spc Fbone    schedule 07.11.2012    source источник


Ответы (3)


Что касается финальной версии facebook sdk для Android 3.0, API изменился, и ответ, предложенный @rightparen, не сработает. В новом API ключевым является использование статического метода Session.openActiveSessionWithAccessToken(). Этот метод предназначен для миграции с fb sdk 2.x на 3.x.

Следующий код работает для меня.

@SuppressWarnings("deprecation")
public static void migrateFbTokenToSession() {
    Facebook facebook = Utils.getFacebookObject();
    AccessToken accessToken = AccessToken.createFromExistingAccessToken(facebook.getAccessToken(), new Date(facebook.getAccessExpires()),
            new Date(facebook.getLastAccessUpdate()), AccessTokenSource.FACEBOOK_APPLICATION_NATIVE, Arrays.asList(Constants.FB_APP_PERMISSIONS));
    Session.openActiveSessionWithAccessToken(ICheezApplication.getContext(), accessToken , new Session.StatusCallback() {

        @Override
        public void call(Session session, SessionState state, Exception exception) {
            sLogger.debug("fbshare Migration to newer icheez state has been successful");
            if(session != null && session.isOpened()) {
                Session.setActiveSession(session);
            }
        }
    });

}
person Community    schedule 19.12.2012

Эта функция может перенести ваше существующее состояние токена, перезаписав состояние токена sdk, кэшированное по умолчанию, с параметрами, которые вы передаете:

private final void migrateToken(String accessToken, long expiresMilliseconds,
                                List<String> permissions, boolean isSSO,
                                long lastRefreshMilliseconds) {
    Bundle bundle = new Bundle();
    TokenCache.putToken(bundle, accessToken);
    TokenCache.putExpirationMilliseconds(bundle, expiresMilliseconds);
    TokenCache.putPermissions(bundle, permissions);
    TokenCache.putLastRefreshMilliseconds(bundle, lastRefreshMilliseconds);
    TokenCache.putIsSSO(bundle, isSSO);

    SharedPreferencesTokenCache cache = new SharedPreferencesTokenCache(this);
    cache.save(bundle);
}

Если у вас нет сохраненных разрешений, вы должны просто передать список разрешений, которые вы запросили, когда получили токен, или пустой ArrayList, если вы ничего не запрашивали или не знаете.

Параметр isSSO указывает, получили ли вы токен с помощью Facebook Login/SSO с приложением facebook (true) или с помощью WebView для входа (false). Токены, полученные через вход через Facebook, могут быть расширены, и это логическое значение определяет, должен ли SDK автоматически пытаться расширить токен.

Эта функция перезаписывает состояние, которое считывается конструктором сеанса. Поэтому, если вы вызываете функцию, вам нужно будет создать сеанс, чтобы использовать его. Логика может выглядеть так:

    Session session = Session.openActiveSession(this);
    if ((session == null) && hasOldTokenState()) {
        migrateToken(...);
        session = Session.openActiveSession(this);
    }
    // if session is still null, user will have to log in...
person rightparen    schedule 09.11.2012
comment
Это означает, что TokenCache API изменился в финальной версии facebook3.0sdk. Этот метод больше не работает. - person Gopinath; 19.12.2012
comment
Теперь есть явная поддержка этого сценария. Вы можете использовать токен AccessToken = AccessToken.createFromExistingAccessToken (accessToken, expiresDate, lastRefreshDate, AccessTokenSource, разрешения); а затем session.open(токен, обратный вызов); или Session.openActiveSessionWithAccessToken(контекст, токен, обратный вызов). - person rightparen; 19.12.2012

Не знаю, как получить этот токен доступа и авторизовать пользователя, но я использую приведенный ниже код для повторного создания сеанса, если сеанс недействителен.

private SessionListener mSessionListener = new SessionListener();

Utility.mFacebook = new Facebook(APP_ID);
Utility.mAsyncRunner = new AsyncFacebookRunner(Utility.mFacebook);
SessionStore.restore(Utility.mFacebook, getApplicationContext());

SessionEvents.addAuthListener(mSessionListener);
SessionEvents.addLogoutListener(mSessionListener);

Мой класс SessionEvent:

открытый класс SessionEvents {

private static LinkedList<AuthListener> mAuthListeners = new LinkedList<AuthListener>();
private static LinkedList<LogoutListener> mLogoutListeners = new LinkedList<LogoutListener>();

/**
 * Associate the given listener with this Facebook object. The listener's
 * callback interface will be invoked when authentication events occur.
 * 
 * @param listener
 *            The callback object for notifying the application when auth
 *            events happen.
 */
public static void addAuthListener(AuthListener listener) {
    mAuthListeners.add(listener);
}

/**
 * Remove the given listener from the list of those that will be notified
 * when authentication events occur.
 * 
 * @param listener
 *            The callback object for notifying the application when auth
 *            events happen.
 */
public static void removeAuthListener(AuthListener listener) {
    mAuthListeners.remove(listener);
}

/**
 * Associate the given listener with this Facebook object. The listener's
 * callback interface will be invoked when logout occurs.
 * 
 * @param listener
 *            The callback object for notifying the application when log out
 *            starts and finishes.
 */
public static void addLogoutListener(LogoutListener listener) {
    mLogoutListeners.add(listener);
}

/**
 * Remove the given listener from the list of those that will be notified
 * when logout occurs.
 * 
 * @param listener
 *            The callback object for notifying the application when log out
 *            starts and finishes.
 */
public static void removeLogoutListener(LogoutListener listener) {
    mLogoutListeners.remove(listener);
}

public static void onLoginSuccess() {
    for (AuthListener listener : mAuthListeners) {
        listener.onAuthSucceed();
    }
}

public static void onLoginError(String error) {
    for (AuthListener listener : mAuthListeners) {
        listener.onAuthFail(error);
    }
}

public static void onLogoutBegin() {
    for (LogoutListener l : mLogoutListeners) {
        l.onLogoutBegin();
    }
}

public static void onLogoutFinish() {
    for (LogoutListener l : mLogoutListeners) {
        l.onLogoutFinish();
    }
}

/**
 * Callback interface for authorization events.
 */
public static interface AuthListener {

    /**
     * Called when a auth flow completes successfully and a valid OAuth
     * Token was received. Executed by the thread that initiated the
     * authentication. API requests can now be made.
     */
    public void onAuthSucceed();

    /**
     * Called when a login completes unsuccessfully with an error.
     * 
     * Executed by the thread that initiated the authentication.
     */
    public void onAuthFail(String error);
}

/**
 * Callback interface for logout events.
 */
public static interface LogoutListener {
    /**
     * Called when logout begins, before session is invalidated. Last chance
     * to make an API call. Executed by the thread that initiated the
     * logout.
     */
    public void onLogoutBegin();

    /**
     * Called when the session information has been cleared. UI should be
     * updated to reflect logged-out state.
     * 
     * Executed by the thread that initiated the logout.
     */
    public void onLogoutFinish();
}

}

Может быть, это поможет вам.

person Shreyash Mahajan    schedule 07.11.2012
comment
Вы используете класс Facebook в своем коде, согласно документации класса Facebook по ссылке ниже, этот класс устарел/не рекомендуется, developers.facebook.com/docs/reference/android/3.0/Facebook - person Spc Fbone; 07.11.2012
comment
@SpcFbone: хорошо, хорошо. Я говорю о том, что я использую раньше и мне очень помогает. Может быть полезно для вас. - person Shreyash Mahajan; 07.11.2012
comment
[1] В вашем коде кажется, что вы не используете сохраненный токен доступа для создания сеанса? [2] Я пробую образец с именем hackbook, приведенный в последнем Android SDK FB facebook-android-sdk-3.0.b... Это приложение также использует аналогичную концепцию, но проблема в том, что при каждом запуске приложения оно запрашивает войти в аккаунт ФБ. Итак, вы также столкнулись с подобной проблемой или каким-либо обходным путем? - person Spc Fbone; 08.11.2012
comment
Нет, я не сталкиваюсь с такой проблемой. Однажды, если я войду в Facebook, он больше никогда не спросит меня, пока я не выйду из Facebook или не удалю приложение и не переустановлю его снова. - person Shreyash Mahajan; 08.11.2012
comment
Я использую то же самое (Hackbook of facebook) для входа в систему, и он отлично работает. Кроме того, если сеанс недействителен, я использую приведенный выше код для повторного создания сеанса facebook. - person Shreyash Mahajan; 08.11.2012