<p>尽管Simon Cross的答案被接受并且是正确的,但我想我可以用一个例子(Android)来说明需要做什么。我会尽我所能保持它的概括性,只关注这个问题。就我个人而言,我将东西存储在一个数据库中,因此加载是平滑的,但这需要一个CursorAdapter和ContentProvider,这有点超出了这里的范围。</p>
<p>我自己来到这里,然后想,现在怎么了?!</p>
<p><strong>问题</strong></p>
<p>就像<em>user3594351</em>一样,我注意到朋友的数据是空白的。我是用FriendPickerFragment发现的。三个月前起作用的,现在不起作用了。甚至连Facebook的例子都被打破了。所以我的问题是“如何手工创建FriendPickerFragment?”?</p>
<p><strong>什么不起作用</strong></p>
<p><em>Simon Cross</em>中的选项1不够强大,无法邀请朋友加入应用程序。<em>Simon Cross</em>也推荐了Requests对话框,但一次只允许五个请求。在任何给定的Facebook登录会话中,“请求”对话框也显示相同的朋友。没用。</p>
<p><strong>什么有效(摘要)</strong></p>
<p>选择2和一些艰苦的工作。你必须确保你符合Facebook的新规则:1)你是一个游戏2)你有一个画布应用(网络状态)3)你的应用已在Facebook注册。这都是在Facebook开发者网站的<em>设置</em>下完成的。</p>
<p>为了在我的应用程序中手动模拟好友选取器,我执行了以下操作:</p>
<ol>
<li>创建一个显示两个片段的选项卡活动。每个片段都显示一个列表。一个片段表示可用的朋友(<em>/me/friends</em>),另一个片段表示不可邀请的朋友(<em>/me/invitable\u friends</em>)。使用相同的片段代码呈现两个选项卡。</li>
<li>创建一个异步任务,从Facebook获取好友数据。加载数据后,将其丢到适配器,适配器将把值呈现到屏幕上。</li>
</ol>
<p><strong>详细信息</strong></p>
<p>异步任务</p>
<pre><code>private class DownloadFacebookFriendsTask extends AsyncTask<FacebookFriend.Type, Boolean, Boolean> {
private final String TAG = DownloadFacebookFriendsTask.class.getSimpleName();
GraphObject graphObject;
ArrayList<FacebookFriend> myList = new ArrayList<FacebookFriend>();
@Override
protected Boolean doInBackground(FacebookFriend.Type... pickType) {
//
// Determine Type
//
String facebookRequest;
if (pickType[0] == FacebookFriend.Type.AVAILABLE) {
facebookRequest = "/me/friends";
} else {
facebookRequest = "/me/invitable_friends";
}
//
// Launch Facebook request and WAIT.
//
new Request(
Session.getActiveSession(),
facebookRequest,
null,
HttpMethod.GET,
new Request.Callback() {
public void onCompleted(Response response) {
FacebookRequestError error = response.getError();
if (error != null && response != null) {
Log.e(TAG, error.toString());
} else {
graphObject = response.getGraphObject();
}
}
}
).executeAndWait();
//
// Process Facebook response
//
//
if (graphObject == null) {
return false;
}
int numberOfRecords = 0;
JSONArray dataArray = (JSONArray) graphObject.getProperty("data");
if (dataArray.length() > 0) {
// Ensure the user has at least one friend ...
for (int i = 0; i < dataArray.length(); i++) {
JSONObject jsonObject = dataArray.optJSONObject(i);
FacebookFriend facebookFriend = new FacebookFriend(jsonObject, pickType[0]);
if (facebookFriend.isValid()) {
numberOfRecords++;
myList.add(facebookFriend);
}
}
}
// Make sure there are records to process
if (numberOfRecords > 0){
return true;
} else {
return false;
}
}
@Override
protected void onProgressUpdate(Boolean... booleans) {
// No need to update this, wait until the whole thread finishes.
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
/*
User the array "myList" to create the adapter which will control showing items in the list.
*/
} else {
Log.i(TAG, "Facebook Thread unable to Get/Parse friend data. Type = " + pickType);
}
}
}
</code></pre>
<p>我创建的FacebookFriend类</p>
<pre><code>public class FacebookFriend {
String facebookId;
String name;
String pictureUrl;
boolean invitable;
boolean available;
boolean isValid;
public enum Type {AVAILABLE, INVITABLE};
public FacebookFriend(JSONObject jsonObject, Type type) {
//
//Parse the Facebook Data from the JSON object.
//
try {
if (type == Type.INVITABLE) {
//parse /me/invitable_friend
this.facebookId = jsonObject.getString("id");
this.name = jsonObject.getString("name");
// Handle the picture data.
JSONObject pictureJsonObject = jsonObject.getJSONObject("picture").getJSONObject("data");
boolean isSilhouette = pictureJsonObject.getBoolean("is_silhouette");
if (!isSilhouette) {
this.pictureUrl = pictureJsonObject.getString("url");
} else {
this.pictureUrl = "";
}
this.invitable = true;
} else {
// Parse /me/friends
this.facebookId = jsonObject.getString("id");
this.name = jsonObject.getString("name");
this.available = true;
this.pictureUrl = "";
}
isValid = true;
} catch (JSONException e) {
Log.w("#", "Warnings - unable to process Facebook JSON: " + e.getLocalizedMessage());
}
}
}
</code></pre>