Каков код для получения обновленного токена 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 г.
Пожалуйста, не предлагайте вместо этого использовать функцию exteAccessTokenIfNeeded в onResume(). У меня также есть проблемы с этим, и именно поэтому я смотрю на обновление токена Graph API:-)
Связанные вопросы переполнения стека
Можно ли расширить маркеры Facebook с помощью exteAccessTokenIfNeeded в приложении для Android? (мой вопрос)
Как будет работать offline_access после устаревания после 1 мая?
Маркер доступа Facebook не может быть продлен
Защита секрета приложения для использования exteAccessToken (Java/Android)
Соответствующие ссылки на Facebook
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 должен быть простым.