Facebook的朋友选择器SDK示例无法运行Android

请帮我用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
05-08 16:42:20.453: I/QCNEA(28696): |NIMS| getaddrinfo: hostname graph.facebook.com servname NULL numeric 4 appname
05-08 16:51:32.482: D/Request(31861): Warning: Sessionless Request needs token but missing either application ID or client token

另外,我正在制作完整的代码供您参考

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 selectedUsers; public List getSelectedUsers() { return selectedUsers; } public void setSelectedUsers(List selectedUsers) { this.selectedUsers = selectedUsers; } }

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 PERMISSIONS = new ArrayList() { { 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 getMissingPermissions(Session session) { List missingPerms = new ArrayList(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 selection = application.getSelectedUsers(); if (selection != null && selection.size() > 0) { ArrayList names = new ArrayList(); for (GraphUser user : selection) { names.add(user.getName()); } results = TextUtils.join(", ", names); } else { results = ""; } 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; } } } 

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

AndroidManifest.xml中

                    

经过长时间的斗争,我找到了自己的解决方案来解决上述问题。 Facebook最近发布了他们的新SDK,以提高安全性。 在您的应用中使用facebook SDK有一些要求。

  1. 该应用程序应该发送提交,并需要Facebook批准才能在Facebook内使用,以使您自己的应用程序显示朋友的详细信息,访问位置和其他特殊权限批准手续类似于谷歌app store的批准手续。

  2. 该应用程序必须列在Google Play中,或者您可以将其作为测试用户进行集成(例如,在Google Play中进行beta测试)。

  3. 应用程序应具有正确的程序包名称,启动活动,域名,网站URL和电子邮件。

  4. 注册的应用程序ID必须与必须为在不同计算机上开发的用户生成的应用程序名称哈希密钥匹配

  5. 需要添加基本的应用程序信息,包括屏幕截图描述应用程序徽标

  6. 成功批准后,将在您的应用名称附近显示“有效”符号。

我希望这对别人有用 !!!

有关Facebook网站的更多信息 。

花了很多时间试图解决这个问题后,我想为仍在寻找的人添加以下内容:

  1. 您将在列表中看到的具有user_friend权限的唯一朋友是已登录并批准您的应用的其他用户。 即如果没有其他人使用它,你将不会在列表中(我知道,如果你全部阅读,这是显而易见的)
  2. 最简单的测试方法是设置测试应用程序,在“角色”下的facebook界面中添加测试用户,确保测试用户是朋友,然后在应用程序上每次使用时登录。 只有这样他们才会出现在列表中。
  3. 除非你特别要求,否则你的应用程序将不具有user_friends权限(但是,你不需要通过Facebook查看它,因为它是基本权限的一部分) – 我将它添加到Splash Segment中的onCreateView(来自SDK中的Scrumptios / Login示例如下:

     LoginButton loginButton = (LoginButton) view.findViewById(R.id.login_button); loginButton.setReadPermissions(Arrays.asList("user_friends")); 
  4. 使用Facebook测试用户界面作为测试用户登录Facebook,以validation他们是否已接受正确的权限(在应用程序下)。