Каков код для получения обновленного токена Facebook в приложении для Android?

Я разрабатываю приложение для Android. В связи с предстоящим устареванием разрешения Facebook offline_access я пытаюсь использовать Graph API для расширения токена Facebook.

        https://graph.facebook.com/oauth/access_token?             
        client_id=APP_ID&
        client_secret=APP_SECRET&
        grant_type=fb_exchange_token&
        fb_exchange_token=EXISTING_ACCESS_TOKEN

Может ли кто-нибудь предоставить подробный код, демонстрирующий, как реализовать приведенный выше код в приложении для Android и получить обновленный токен Facebook?

Спасибо за уделенное время.

Обновление второе:

Прогресс (я думаю)!

Использование полного URL-адреса с методом запроса facebook приводит к тому, что базовый URL-адрес добавляется в начало URL-адреса. Таким образом, вместо

String refreshUrl = "https://graph.facebook.com/oauth/access_token?client_id=12345678910&client_secret=abcdefghijklmnopqrstuvwxyz&grant_type=fb_exchange_token&fb_exchange_token="+currentAccessToken;

следует использовать

String refreshUrl = "oauth/access_token?client_id=12345678910&client_secret=abcdefghijklmnopqrstuvwxyz&grant_type=fb_exchange_token&fb_exchange_token="+currentAccessToken;

Однако теперь я получаю ответ {"error":{"message":"Ошибка проверки приложения. Неверный идентификатор приложения.","type":"OAuthException","code":190}}

Первое обновление:

Вот что я пробовал. Код завершается, то есть вызывается OnComplete на листере, НО ответ не содержит нового токена доступа или значения истечения срока действия.

    void refreshWithGraph() {
        AsyncFacebookRunner extendingAsyncRunner = new AsyncFacebookRunner(facebook);
        Bundle parameters = new Bundle();

        //the variable currentAccessToken is obtained after authorisation is complete using currentAccessToken = facebook.getAccessToken();

        String refreshUrl = "https://graph.facebook.com/oauth/access_token?client_id=12345678910&client_secret=abcdefghijklmnopqrstuvwxyz&grant_type=fb_exchange_token&fb_exchange_token="+currentAccessToken;


    extendingAsyncRunner.request(refreshUrl, parameters, new RefreshListener(), null );
   }

Вот моя версия RefreshListener...

  //REFRESH LISTENER
    public class RefreshListener extends BaseRequestListener {

        public void onComplete(final String response, Object state) {


            try {
               final JSONObject json = Util.parseJson(response);

                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {             
                        tvRefreshResponse.setText("IN REFRESH LISTENER ONCOMPLETE\nResponse is " + response);
                        tvRefreshToken.setText("IN REFRESH LISTENER ONCOMPLETE\nToken is " + facebook.getAccessToken());
                        tvRefreshExpiry.setText("IN REFRESH LISTENER ONCOMPLETE\nFacebook expiry is " + millisecToDate(facebook.getAccessExpires()));

                    }

                }); //end runOnUiThread



            } catch (JSONException e) {
                runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                tvRefreshResponse.setText("IN REFRESH LISTENER ONCOMPLETE CAUGHT JSON EXCEPTION \nResponse is " + response);

                            }

                         }); //end runOnUiThread

            } catch (FacebookError fe) {
                runOnUiThread(new Runnable() {


                            @Override
                            public void run() {
                                tvRefreshResponse.setText("IN REFRESH LISTENER ONCOMPLETE CAUGHT FACEBOOK ERROR \nResponse is " + response);

                            }

                         }); //end runOnUiThread
            } //end catch Facebook error

        }  //end onComplete


        @Override
        public void onIOException(IOException e, Object state) {
            tvRefreshResponse.setText("IN REFRESH LISTENER IOEXCEPTION \nException is "+ e.getLocalizedMessage());

        }

        @Override
        public void onFileNotFoundException(FileNotFoundException e, Object state) {
            tvRefreshResponse.setText("IN REFRESH LISTENER FILE NOT FOUND EXCEPTION \nException is "+ e.getLocalizedMessage());
        }

        @Override
        public void onMalformedURLException(MalformedURLException e, Object state) {
            tvRefreshResponse.setText("IN REFRESH MALFORMED URL \nException is "+ e.getLocalizedMessage());

        }

        @Override
        public void onFacebookError(FacebookError e, Object state) {
            tvRefreshResponse.setText("IN REFRESH ONFACEBOOK ERROR \nException is "+ e.getLocalizedMessage());

        }
    } //end RefreshListener

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

 {"id":"https:\/\/graph.facebook.com\/oauth\/access_token","shares":78,"comments":1}

Когда я помещаю тот же URL-адрес (с буквенно-цифровым текущим значением токена) в веб-браузер, ответ ДЕЙСТВИТЕЛЬНО включает токен доступа.


Связанная информация

Разрешение Facebook offline_access будет прекращено 1 мая 2012 г.

Пожалуйста, не предлагайте вместо этого использовать функцию extendAccessTokenIfNeeded в onResume(). У меня тоже проблемы с этим, и это причина, по которой я изучаю обновление токена Graph API :-)

Вопросы, связанные с переполнением стека

Можно ли расширить токены Facebook с помощью extendAccessTokenIfNeeded в приложении для Android? (мой вопрос)

Как будет работать offline_access после устаревания после 1 мая?

Токен доступа Facebook не может быть расширен

Защита секрета приложения для использования extendAccessToken (Java/Android)

Соответствующие ссылки на Facebook

Руководство по Android на Facebook

Устаревание разрешений Facebook offline_access


person Mel    schedule 10.04.2012    source источник
comment
Со всеми ссылками выше, зачем вам более подробная информация? Похоже, у вас достаточно документации для реализации этого.   -  person Shreeni    schedule 10.04.2012
comment
Вы могли бы подумать, что я могу решить это, но нет. :-( На все простые вопросы о переполнении стека отвечают очень быстро, поэтому я думаю, что это не так просто, как кажется на первый взгляд...   -  person Mel    schedule 10.04.2012


Ответы (1)


Честно говоря, я немного запутался - похоже, у вас есть все, чтобы сделать это - и это просто. Но позвольте мне попытаться ответить на ваш вопрос. Вот код из моего проекта C#, в котором я расширяю токен приложения своими комментариями на случай, если вы не знакомы с языками и классами C#:

string currentToken = "token from somewhere";

// WebClient is used to send GET request to the given URL
// and receive the response
using (var req = new System.Net.WebClient())
{
    // create URL string and fill it in with data (app Id, secret, and current token)
    var extendTokenUrl = string.Format(
        "https://graph.facebook.com/oauth/access_token?client_id={0}&client_secret={1}&grant_type=fb_exchange_token&fb_exchange_token={2}",
        FB_APP_ID,
        FB_APP_SECRET,
        currentToken);

    // send GET request and download the response
    var response = req.DownloadString(extendTokenUrl);

    // if all is good, response will be a string which looks like this:
    // access_token=<<THE TOKEN GOES HERE>>
    var newToken = response.Substring("access_token=".Length);

    // now save newToken in your DB INSTEAD of currentToken - 
    // so all calls will be made with extended token
    SaveTokenInDB(newToken);
}

надеюсь, что это поможет, и перевод этого на Java должен быть простым.

person avs099    schedule 13.04.2012
comment
Привет, спасибо за ваш ответ. Я сам в замешательстве! Мне сказали, что простая задача — не получить никакого ответа от разработчиков Android — даже с наградой в 100 баллов! Моя проблема с кодированием заключается в том, что ответ от Facebook не содержит ключа доступа. Однако, когда я просто помещаю весь URL-адрес в браузер, я получаю ключ доступа. Я обновил свой ответ, чтобы включить мои предыдущие попытки. - person Mel; 17.04.2012
comment
Я сразу заметил, что вы парсите JSON в своем RefreshListener — но я считаю, что это неправильно. Вы не возвращаете JSON, а просто необработанную строку. Кроме того, если вы вставите значение String refreshUrl в браузер, вы получите правильный токен? Вы на 100% уверены, что делаете запрос GET (вместо POST)? Кроме того, у вас есть исходники для AsyncFacebookRunner? можете ли вы узнать, ГДЕ он на самом деле отправляет HTTP-запрос, и указать там точный URL-адрес и метод HTTP? Кроме того, если вы НЕ используете AsyncFacebookRunner, а просто используете стандартный компонент HTTP-запроса, будет ли он работать? - person avs099; 17.04.2012
comment
Спасибо, я делаю успехи... Когда я изменяю код в коде SDK Util.java (это класс, который фактически выполняет HTTP-запрос), я начинаю получать тот же ответ, что и при вводе адреса в браузере. Но теперь я понимаю, что срок годности очень мал (5143168). Когда я обновляю, цифра всегда уменьшается... Есть идеи по этому поводу? Пример ответа... access_token=AAAEparERUxABAFSPLEI8VNAwo8FLsxOpR6bZAgyeRxj0JAtGBBqMv5y3gnMkvy0TMCrnKuF0Jp6S1DSpiO8mmiy3JMBV2XZASAimYwZDZD&expires=5143168 - person Mel; 18.04.2012
comment
expires=5143168 — количество секунд, в течение которых токен действителен, в секундах. Это 59 с лишним дней — это продолжительность, которую FB обещает для расширенного токена. Так вроде все хорошо. - person avs099; 18.04.2012
comment
Спасибо. Я понимаю, что токен на самом деле не обновляется. Когда я пытаюсь обновиться с интервалом в несколько секунд между обновлениями, я получаю тот же токен, и срок действия сокращается всего на несколько секунд. Кажется, я где-то читал (не могу найти), что токены можно обновлять только раз в 24 часа? Как вы думаете, может быть другая причина? - person Mel; 19.04.2012
comment
к сожалению, у меня нет официальной ссылки, у меня также есть ощущение, что я где-то читал примерно за 1 день до того, как токен действительно обновится, но я точно не помню. В любом случае, попробуйте завтра :) - person avs099; 19.04.2012
comment
Сделаю. Спасибо за твою помощь. Я назначил награду (поскольку срок ее действия истекал), и я отмечу вопрос как правильный после того, как обновлю токен с 24-часовым интервалом между обновлениями. Скрещенные пальцы! - person Mel; 19.04.2012