Как разобрать следующую страницу Facebook (SDK 4.0) График ответа в андроиде?
Я загружаю список друзей, которые используют мое приложение для Android, и показываю их в виде списка. Ответ мы получаем от звонка:
GraphRequestAsyncTask graphRequest = new GraphRequest(
AccessToken.getCurrentAccessToken(),
"/me/friends",
null,
HttpMethod.GET,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
}
}
).executeAsync();
является
{
"data": [
{
"name": "Sanjeev Sharma",
"id": "10XXXXXXXXXX40"
},
{
"name": "Avninder Singh",
"id": "1XXXXX30"
},
{
"name": "Saikrishna Tipparapu",
"id": "17XXXXXX98"
},
{
"name": "Perfekt Archer",
"id": "100XXXXX29"
},
{
"name": "Shathyan Raja",
"id": "10XXXXX0"
},
{
"name": "Kenny Tran",
"id": "10XXXXX36164"
},
{
"name": "Lahaul Seth",
"id": "100XXXXX161"
},
{
"name": "Bappa Dittya",
"id": "10XXXXX24"
},
{
"name": "Rahul",
"id": "10XXXXX
},
{
"name": "Suruchi ",
"id": "7XXXXXXXX11"
}
],
"paging": {
"next": "https://graph.facebook.com/76XXXXXXXX28/friends?limit=25&offset=25&__after_id=enc_AdAXXXXX5L8nqEymMrXXXXoYWaK8BXXHrvpXp03gc1eAaVaj7Q"
},
"summary": {
"total_count": 382
}
}
Теперь, как мы можем проанализировать следующую страницу результата в Android, так как это ссылка на следующую страницу? Следующий вызов API будет осуществляться только через Graph API или Facebook?
2 ответа
Если у вас есть правильное представление о том, как использовать разбиение на страницы со следующим, хотя я думаю, что он прав, я просто хотел добавить рекурсивный способ извлечения всех результатов страница за страницей в один красивый объект списка, это из проекта, запрашивающего пользовательские фотографии, но Это та же идея и синтаксис, что и у лайков (обратите внимание, что все это использует execute и wait, поэтому вам придется запускать это из отдельного потока, иначе вы эффективно заблокируете свой поток пользовательского интерфейса и в конечном итоге закроете приложение самостоятельно.
Bundle param = new Bundle();
param.putString("fields", "id,picture");
param.putInt("limit", 100);
//setup a general callback for each graph request sent, this callback will launch the next request if exists.
final GraphRequest.Callback graphCallback = new GraphRequest.Callback(){
@Override
public void onCompleted(GraphResponse response) {
try {
JSONArray rawPhotosData = response.getJSONObject().getJSONArray("data");
for(int j=0; j<rawPhotosData.length();j++){
/*save whatever data you want from the result
JSONObject photo = new JSONObject();
photo.put("id", ((JSONObject)rawPhotosData.get(j)).get("id"));
photo.put("icon", ((JSONObject)rawPhotosData.get(j)).get("picture"));
boolean isUnique = true;
for(JSONObject item : photos){
if(item.toString().equals(photo.toString())){
isUnique = false;
break;
}
}
if(isUnique) photos.add(photo);*/
}
//get next batch of results of exists
GraphRequest nextRequest = response.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
if(nextRequest != null){
nextRequest.setCallback(this);
nextRequest.executeAndWait();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
Теперь все, что вам нужно сделать, это просто сделать первоначальный запрос и установить обратный вызов, который вы сделали на предыдущем шаге, обратный вызов будет обрабатывать всю грязную работу по вызову остальных элементов, это в конечном итоге даст вам все элементы из вашего запрос.
//send first request, the rest should be called by the callback
new GraphRequest(AccessToken.getCurrentAccessToken(),
"me/photos",param, HttpMethod.GET, graphCallback).executeAndWait();
Как уже упоминалось @CBroe, вы используете метод getRequestForPagedResults. Как пример, проверьте пример проекта Scrumpsive.
Я расширил HelloFacebookSample и добавил две кнопки, которые будут загружать начальные понравившиеся пользователю страницы, а другая будет загружать следующий результат, если он доступен:
loadAndLogLikesButton = (Button) findViewById(R.id.loadAndLogLikesButton);
loadAndLogLikesButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pendingAction = PendingAction.LOAD_LIKES;
if (!hasUserLikesPermission()) {
LoginManager.getInstance().logInWithReadPermissions(HelloFacebookSampleActivity.this, Arrays.asList("public_profile", "user_likes"));
} else {
handlePendingAction();
}
}
});
Теперь handlePendingAction()
вызывается из успешного обратного вызова LoginManager. Как видите, у меня есть дополнительное действие LOAD_LIKES
это вызовет метод, который будет делать следующее:
GraphRequest request = GraphRequest.newGraphPathRequest(
accessToken,
"me/likes",
new GraphRequest.Callback() {
@Override
public void onCompleted(GraphResponse response) {
Log.d("HelloFacebook", response.getRawResponse());
JSONArray data = response.getJSONObject().optJSONArray("data");
boolean haveData = data.length() > 0;
if (haveData) {
loadNextLikesButton.setEnabled(true);
nextRequest = response.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
}
}
}
);
Bundle parameters = new Bundle();
parameters.putString("fields", "id");
parameters.putString("limit", "100");
request.setParameters(parameters);
Теперь мой loadNextLikesButton
обратный вызов выглядит так:
if (nextRequest != null) {
nextRequest.setCallback(new GraphRequest.Callback() {
@Override
public void onCompleted(GraphResponse response) {
Log.d("HelloFacebook", response.getRawResponse());
JSONArray data = response.getJSONObject().optJSONArray("data");
boolean haveData = data.length() > 0;
if (haveData) {
loadNextLikesButton.setEnabled(true);
nextRequest = response.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
} else {
loadNextLikesButton.setEnabled(false);
}
}
});
nextRequest.executeAsync();
} else {
Log.d("HelloFacebook", "We are done!");
return;
}
Не красиво, но вы поняли.