【问题标题】:How to parse next page of Facebook (SDK 4.0) Graph response in android?如何在android中解析Facebook(SDK 4.0)图形响应的下一页?
【发布时间】:2015-07-14 05:15:27
【问题描述】:

我正在获取使用我的 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 完成?

【问题讨论】:

  • 有一个专门的方法,getRequestForPagedResults
  • @CBroe 能否分享一段使用此函数解析数据的代码。
  • 您不会使用该方法“解析”任何数据——您只需使用它来获取一个新的GraphRequest 实例,该实例可用于获取下一页或上一页的结果。跨度>
  • @TheOddAbhi,你能看看stackoverflow.com/questions/34679376/…吗?

标签: android facebook facebook-graph-api facebook-sdk-4.0 facebook-graph-api-v2.3


【解决方案1】:

ifaour 对如何使用下一个分页有正确的想法,尽管我认为他是对的我只是想添加一种递归方式来将所有结果页面逐页获取到一个漂亮的列表对象中,这是来自一个项目请求用户照片,但它与喜欢的想法和语法相同(请注意,整个事情都在使用执行和等待,因此您必须从单独的线程运行它,否则您将有效地阻塞您的 UI 线程并最终使应用程序关闭自己下来了。

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

【讨论】:

  • 这是完美的。唯一的问题是,它在最后一页上给出 JSONException,因为在最后一页上找不到 JSON 键。有什么解决方法吗?
  • getRequestForPagedResults 调用为我返回 null。其他人显然也有同样的问题 - stackoverflow.com/questions/34584877/… 这个电话仍然适用于任何人吗?如果是这样,您可以发布您的代码 sn-p 吗?请注意,我在返回的 JSON 中看到了分页项。只是这个调用返回 null。
  • 这一行nextRequest.executeAndWait() 将通过异常:android.os.NetworkOnMainThreadException。改用这个nextRequest.executeAsync(); 在主线程上执行请求。
【解决方案2】:

正如@CBroe 所述,您使用getRequestForPagedResults 方法。例如,查看Scrumptious 示例项目。

我扩展了 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();
    }
  }
});

现在正在从 LoginManager 成功回调中调用 handlePendingAction()。如您所见,我有一个额外的操作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;
}

不漂亮,但你明白了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    相关资源
    最近更新 更多