请帮助我使用3.14 SDK从我的个人资料中获取Facebook好友。代码中没有错误,但问题是在我的个人资料中获取朋友时获得空列表。我在logcat中得到了错误。
05-08 16:18:49.252: E/ActivityThread(25644): Failed to find provider info for com.facebook.orca.provider.PlatformProvider<br>
05-08 16:42:20.453: I/QCNEA(28696): |NIMS| getaddrinfo: hostname graph.facebook.com servname NULL numeric 4 appname <br>
05-08 16:51:32.482: D/Request(31861): Warning: Sessionless Request needs token but missing either application ID or client token<br>
我也在制作完整的代码供您参考以下
FriendPickerApplication.java *
package com.facebook.samples.friendpicker;
import android.app.Application;
import com.facebook.model.GraphUser;
import java.util.List;
// We use a custom Application class to store our minimal state data (which users have been selected).
// A real-world application will likely require a more robust data model.
public class FriendPickerApplication extends Application {
private List<GraphUser> selectedUsers;
public List<GraphUser> getSelectedUsers() {
return selectedUsers;
}
public void setSelectedUsers(List<GraphUser> selectedUsers) {
this.selectedUsers = selectedUsers;
}
}<br>
FriendPickerSampleActivity.java
package com.facebook.samples.friendpicker;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.facebook.AppEventsLogger;
import com.facebook.Session.NewPermissionsRequest;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphUser;
import com.facebook.Session;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class FriendPickerSampleActivity extends FragmentActivity {
private static final List<String> PERMISSIONS = new ArrayList<String>() {
{
add("user_friends");
add("public_profile");
}
};
private static final int PICK_FRIENDS_ACTIVITY = 1;
private Button pickFriendsButton;
private TextView resultsTextView;
private UiLifecycleHelper lifecycleHelper;
boolean pickFriendsWhenSessionOpened;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
resultsTextView = (TextView) findViewById(R.id.resultsTextView);
pickFriendsButton = (Button) findViewById(R.id.pickFriendsButton);
pickFriendsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onClickPickFriends();
}
});
lifecycleHelper = new UiLifecycleHelper(this, new Session.StatusCallback() {
@Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChanged(session, state, exception);
}
});
lifecycleHelper.onCreate(savedInstanceState);
ensureOpenSession();
}
@Override
protected void onStart() {
super.onStart();
// Update the display every time we are started.
displaySelectedFriends(RESULT_OK);
}
@Override
protected void onResume() {
super.onResume();
// Call the 'activateApp' method to log an app event for use in analytics and advertising reporting. Do so in
// the onResume methods of the primary Activities that an app may be launched into.
AppEventsLogger.activateApp(this);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICK_FRIENDS_ACTIVITY:
displaySelectedFriends(resultCode);
break;
default:
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
break;
}
}
private boolean ensureOpenSession() {
if (Session.getActiveSession() == null ||
!Session.getActiveSession().isOpened()) {
Session.openActiveSession(
this,
true,
PERMISSIONS,
new Session.StatusCallback() {
@Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChanged(session, state, exception);
}
});
return false;
}
return true;
}
private boolean sessionHasNecessaryPerms(Session session) {
if (session != null && session.getPermissions() != null) {
for (String requestedPerm : PERMISSIONS) {
if (!session.getPermissions().contains(requestedPerm)) {
return false;
}
}
return true;
}
return false;
}
private List<String> getMissingPermissions(Session session) {
List<String> missingPerms = new ArrayList<String>(PERMISSIONS);
if (session != null && session.getPermissions() != null) {
for (String requestedPerm : PERMISSIONS) {
if (session.getPermissions().contains(requestedPerm)) {
missingPerms.remove(requestedPerm);
}
}
}
return missingPerms;
}
private void onSessionStateChanged(final Session session, SessionState state, Exception exception) {
if (state.isOpened() && !sessionHasNecessaryPerms(session)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.need_perms_alert_text);
builder.setPositiveButton(
R.string.need_perms_alert_button_ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
session.requestNewReadPermissions(
new NewPermissionsRequest(
FriendPickerSampleActivity.this,
getMissingPermissions(session)));
}
});
builder.setNegativeButton(
R.string.need_perms_alert_button_quit,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.show();
} else if (pickFriendsWhenSessionOpened && state.isOpened()) {
pickFriendsWhenSessionOpened = false;
startPickFriendsActivity();
}
}
private void displaySelectedFriends(int resultCode) {
String results = "";
FriendPickerApplication application = (FriendPickerApplication) getApplication();
Collection<GraphUser> selection = application.getSelectedUsers();
if (selection != null && selection.size() > 0) {
ArrayList<String> names = new ArrayList<String>();
for (GraphUser user : selection) {
names.add(user.getName());
}
results = TextUtils.join(", ", names);
} else {
results = "<No friends selected>";
}
resultsTextView.setText(results);
}
private void onClickPickFriends() {
startPickFriendsActivity();
}
private void startPickFriendsActivity() {
if (ensureOpenSession()) {
Intent intent = new Intent(this, PickFriendsActivity.class);
// Note: The following line is optional, as multi-select behavior is the default for
// FriendPickerFragment. It is here to demonstrate how parameters could be passed to the
// friend picker if single-select functionality was desired, or if a different user ID was
// desired (for instance, to see friends of a friend).
PickFriendsActivity.populateParameters(intent, null, true, true);
startActivityForResult(intent, PICK_FRIENDS_ACTIVITY);
} else {
pickFriendsWhenSessionOpened = true;
}
}
} <br>
PickFriendsActivity.java
package com.facebook.samples.friendpicker;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.widget.Toast;
import com.facebook.FacebookException;
import com.facebook.model.GraphUser;
import com.facebook.widget.FriendPickerFragment;
import com.facebook.widget.PickerFragment;
import java.util.List;
public class PickFriendsActivity extends FragmentActivity {
FriendPickerFragment friendPickerFragment;
public static void populateParameters(Intent intent, String userId,
boolean multiSelect, boolean showTitleBar) {
intent.putExtra(FriendPickerFragment.USER_ID_BUNDLE_KEY, userId);
intent.putExtra(FriendPickerFragment.MULTI_SELECT_BUNDLE_KEY,
multiSelect);
intent.putExtra(FriendPickerFragment.SHOW_TITLE_BAR_BUNDLE_KEY,
showTitleBar);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pick_friends_activity);
FragmentManager fm = getSupportFragmentManager();
if (savedInstanceState == null) {
// First time through, we create our fragment programmatically.
final Bundle args = getIntent().getExtras();
friendPickerFragment = new FriendPickerFragment(args);
fm.beginTransaction()
.add(R.id.friend_picker_fragment, friendPickerFragment)
.commit();
} else {
// Subsequent times, our fragment is recreated by the framework and
// already has saved and
// restored its state, so we don't need to specify args again. (In
// fact, this might be
// incorrect if the fragment was modified programmatically since it
// was created.)
friendPickerFragment = (FriendPickerFragment) fm
.findFragmentById(R.id.friend_picker_fragment);
}
friendPickerFragment
.setOnErrorListener(new PickerFragment.OnErrorListener() {
@Override
public void onError(PickerFragment<?> fragment,
FacebookException error) {
PickFriendsActivity.this.onError(error);
}
});
friendPickerFragment
.setOnDoneButtonClickedListener(new PickerFragment.OnDoneButtonClickedListener() {
@Override
public void onDoneButtonClicked(PickerFragment<?> fragment) {
// We just store our selection in the Application for
// other activities to look at.
FriendPickerApplication application = (FriendPickerApplication) getApplication();
application.setSelectedUsers(friendPickerFragment
.getSelection());
setResult(RESULT_OK, null);
finish();
}
});
}
private void onError(Exception error) {
String text = getString(R.string.exception, error.getMessage());
Toast toast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
toast.show();
}
@Override
protected void onStart() {
super.onStart();
try {
FriendPickerApplication application = (FriendPickerApplication) getApplication();
List<GraphUser> selectedUsers = application.getSelectedUsers();
if (selectedUsers != null && !selectedUsers.isEmpty()) {
friendPickerFragment.setSelection(selectedUsers);
}
// Load data, unless a query has already taken place.
friendPickerFragment.loadData(false);
} catch (Exception ex) {
onError(ex);
}
}
}<br>
的AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.facebook.samples.friendpicker"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:name=".FriendPickerApplication"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar" >
<activity
android:name="FriendPickerSampleActivity"
android:label="@string/app_name"
android:windowSoftInputMode="adjustResize" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="PickFriendsActivity"
android:label="Pick Friends" >
</activity>
<activity
android:name="com.facebook.LoginActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/app_id" />
<provider
android:name="com.facebook.NativeAppCallContentProvider"
android:authorities="com.facebook.app.NativeAppCallContentProvider1441068969495032"
android:exported="true" />
</application>
</manifest>
答案 0 :(得分:9)
经过长时间的斗争,我找到了自己的解决方案来解决上述问题。 Facebook最近发布了他们的新SDK,以提高安全性。在您的应用中使用Facebook SDK有一些要求。
该应用应该发送提交,并需要通过 Facebook 批准才能在Facebook内使用,以使您自己的应用能够显示朋友的详细信息,访问位置和其他特殊权限审批手续与Google Play中的应用商店类似。
该应用程序必须列在Google Play中,或者您可以将其作为测试用户进行整合(例如在Google Play中进行beta测试)。
应用程序应具有正确的程序包名称,启动活动,域名,网站URL和电子邮件。
注册的 app id 必须与应用名称和哈希密钥匹配,必须为在<强>不同的机器
需要添加基本的应用程序信息,包括屏幕截图,描述和应用程序徽标
成功获得批准后,一个&#34;活跃的&#34;符号将显示在您的应用名称附近。
我希望这对其他人有用 !!!
答案 1 :(得分:7)
在花了很多时间试图解决这个问题后,我想为仍在寻找的人添加以下内容:
除非你具体要求它,否则你的应用程序将不具有user_friends权限(但是,你不需要通过Facebook查看它,因为它是基本权限的一部分) - 我将它添加到onCreateView在Splash Segment中(来自SDK中的Scrumptios / Login示例),如下所示:
LoginButton loginButton = (LoginButton) view.findViewById(R.id.login_button);
loginButton.setReadPermissions(Arrays.asList("user_friends"));
使用Facebook测试用户界面作为测试用户在Facebook上登录,以验证他们是否已接受正确的权限(在应用程序下)。