android - Facebook 不显示好友列表

标签 android facebook facebook-login

我正在学习 Facebook SDK Scrumptious 教程。我成功完成了登录和个性化步骤。现在我卡在了 Show Me 步骤。

当我点击选择好友时,好友列表是空的。

我将我的兄弟添加为该应用程序的测试员,他在他的 Facebook 开发者页面中点击了接受。然后,在 Eclipse 上,我在他的手机上运行了应用程序。但是当他点击选择 friend 时,它仍然是空的。它没有显示我的名字。当我在手机上运行该应用程序时,我没有在好友列表中看到他的名字。

有人知道为什么我在好友列表中看不到他的名字吗? 该应用程序适用于我们的两部手机,但好友列表为空。

我是按照教程一步步来的。

我相信我使用的哈希键是正确的,因为该应用程序在我们的两部手机上都打开了。有没有我应该实现的新东西,而 Facebook 还没有更新他们的教程?

是不是Eclipse的问题?

主 Activity .java

public class MainActivity extends FragmentActivity  {

    private static final int SPLASH = 0;
    private static final int SELECTION = 1;
    private static final int SETTINGS = 2;
    private static final int FRAGMENT_COUNT = SETTINGS +1;

    private MenuItem settings;

    private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];

    private boolean isResumed = false;

    private UiLifecycleHelper uiHelper;
    private Session.StatusCallback callback = 
        new Session.StatusCallback() {
        @Override
        public void call(Session session, 
                SessionState state, Exception exception) {
            onSessionStateChange(session, state, exception);
        }
    };

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // only add the menu when the selection fragment is showing
        if (fragments[SELECTION].isVisible()) {
            if (menu.size() == 0) {
                settings = menu.add(R.string.settings);
            }
            return true;
        } else {
            menu.clear();
            settings = null;
        }
        return false;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.equals(settings)) {
            showFragment(SETTINGS, true);
            return true;
        }
        return false;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        uiHelper = new UiLifecycleHelper(this, callback);
        uiHelper.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        FragmentManager fm = getSupportFragmentManager();
        fragments[SPLASH] = fm.findFragmentById(R.id.splashFragment);
        fragments[SELECTION] = fm.findFragmentById(R.id.selectionFragment);
        fragments[SETTINGS] = fm.findFragmentById(R.id.userSettingsFragment);

        FragmentTransaction transaction = fm.beginTransaction();
        for(int i = 0; i < fragments.length; i++) {
            transaction.hide(fragments[i]);
        }
        transaction.commit();
    }

    private void showFragment(int fragmentIndex, boolean addToBackStack) {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();
        for (int i = 0; i < fragments.length; i++) {
            if (i == fragmentIndex) {
                transaction.show(fragments[i]);
            } else {
                transaction.hide(fragments[i]);
            }
        }
        if (addToBackStack) {
            transaction.addToBackStack(null);
        }
        transaction.commit();
    }   

    @Override
    public void onResume() {
        super.onResume();
        uiHelper.onResume();
        isResumed = true;
    }

    @Override
    public void onPause() {
        super.onPause();
        uiHelper.onPause();
        isResumed = false;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        uiHelper.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        uiHelper.onDestroy();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        uiHelper.onSaveInstanceState(outState);
    }
    private void onSessionStateChange(Session session, SessionState state, Exception exception) {
        // Only make changes if the activity is visible
        if (isResumed) {
            FragmentManager manager = getSupportFragmentManager();
            // Get the number of entries in the back stack
            int backStackSize = manager.getBackStackEntryCount();
            // Clear the back stack
            for (int i = 0; i < backStackSize; i++) {
                manager.popBackStack();
            }
            if (state.isOpened()) {
                // If the session state is open:
                // Show the authenticated fragment
                showFragment(SELECTION, false);

            } else if (state.isClosed()) {
                // If the session state is closed:
                // Show the login fragment
                showFragment(SPLASH, false);
            }
        }
    }

    @Override
    protected void onResumeFragments() {
        super.onResumeFragments();
        Session session = Session.getActiveSession();

        if (session != null && session.isOpened()) {
            // if the session is already open,
            // try to show the selection fragment
            showFragment(SELECTION, false);
        } else {
            // otherwise present the splash screen
            // and ask the person to login.
            showFragment(SPLASH, false);
        }
    }
}

飞溅 fragment .java

public class SplashFragment extends Fragment{

    @Override
    public View onCreateView(LayoutInflater inflater, 
            ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.splash, 
                container, false);
        return view;
    }
}

选择 fragment .java

public class SelectionFragment extends Fragment{

    private static final String TAG = "SelectionFragment";
    private static final int REAUTH_ACTIVITY_CODE = 100;

    private ProfilePictureView profilePictureView;
    private TextView userNameView;

    private ListView listView;
    private List<BaseListElement> listElements;

    private UiLifecycleHelper uiHelper;
    private Session.StatusCallback callback = new Session.StatusCallback() {
        @Override
        public void call(final Session session, final SessionState state, final Exception exception) {
            onSessionStateChange(session, state, exception);
        }
    };

    private class ActionListAdapter extends ArrayAdapter<BaseListElement> {
        private List<BaseListElement> listElements;

        public ActionListAdapter(Context context, int resourceId, 
                                 List<BaseListElement> listElements) {
            super(context, resourceId, listElements);
            this.listElements = listElements;
            // Set up as an observer for list item changes to
            // refresh the view.
            for (int i = 0; i < listElements.size(); i++) {
                listElements.get(i).setAdapter(this);
            }
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;
            if (view == null) {
                LayoutInflater inflater =
                        (LayoutInflater) getActivity()
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = inflater.inflate(R.layout.listitem, null);
            }

            BaseListElement listElement = listElements.get(position);
            if (listElement != null) {
                view.setOnClickListener(listElement.getOnClickListener());
                ImageView icon = (ImageView) view.findViewById(R.id.icon);
                TextView text1 = (TextView) view.findViewById(R.id.text1);
                TextView text2 = (TextView) view.findViewById(R.id.text2);
                if (icon != null) {
                    icon.setImageDrawable(listElement.getIcon());
                }
                if (text1 != null) {
                    text1.setText(listElement.getText1());
                }
                if (text2 != null) {
                    text2.setText(listElement.getText2());
                }
            }
            return view;
        }

    }

    private class PeopleListElement extends BaseListElement {

        public PeopleListElement(int requestCode) {
            super(getActivity().getResources().getDrawable(R.drawable.add_friends),
                  getActivity().getResources().getString(R.string.action_people),
                  getActivity().getResources().getString(R.string.action_people_default),
                  requestCode);
        }

        @Override
        protected View.OnClickListener getOnClickListener() {
            return new View.OnClickListener() {
                @Override
                public void onClick(View view) {
//                  <del>// Do nothing for now</del>
                    startPickerActivity(PickerActivity.FRIEND_PICKER, getRequestCode());
                }
            };
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        uiHelper = new UiLifecycleHelper(getActivity(), callback);
        uiHelper.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.selection, container, false);

        // Find the user's profile picture custom view
        profilePictureView = (ProfilePictureView) view.findViewById(R.id.selection_profile_pic);
        profilePictureView.setCropped(true);

        // Find the user's name view
        userNameView = (TextView) view.findViewById(R.id.selection_user_name);

     // Find the list view
        listView = (ListView) view.findViewById(R.id.selection_list);

        // Set up the list view items, based on a list of
        // BaseListElement items
        listElements = new ArrayList<BaseListElement>();
        // Add an item for the friend picker
        listElements.add(new PeopleListElement(0));
        // Set the list view adapter
        listView.setAdapter(new ActionListAdapter(getActivity(), 
                            R.id.selection_list, listElements));

        // Check for an open session
        Session session = Session.getActiveSession();
        if (session != null && session.isOpened()) {
            // Get the user's data
            makeMeRequest(session);
        }    
        return view;
    }

    private void makeMeRequest(final Session session) {
        // Make an API call to get user data and define a 
        // new callback to handle the response.
        Request request = Request.newMeRequest(session, 
                new Request.GraphUserCallback() {
            @Override
            public void onCompleted(GraphUser user, Response response) {
                // If the response is successful
                if (session == Session.getActiveSession()) {
                    if (user != null) {
                        // Set the id for the ProfilePictureView
                        // view that in turn displays the profile picture.
                        profilePictureView.setProfileId(user.getId());
                        // Set the Textview's text to the user's name.
                        userNameView.setText(user.getName());
                    }
                }
                if (response.getError() != null) {
                    // Handle errors, will do so later.
                }
            }
        });
        request.executeAsync();
    } 

    private void onSessionStateChange(final Session session, SessionState state, Exception exception) {
        if (session != null && session.isOpened()) {
            // Get the user's data.
            makeMeRequest(session);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REAUTH_ACTIVITY_CODE) {
          uiHelper.onActivityResult(requestCode, resultCode, data);
        } else if (resultCode == Activity.RESULT_OK) {
            // Do nothing for now
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        uiHelper.onResume();
    }

    @Override
    public void onSaveInstanceState(Bundle bundle) {
        super.onSaveInstanceState(bundle);
        uiHelper.onSaveInstanceState(bundle);
    }

    @Override
    public void onPause() {
        super.onPause();
        uiHelper.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        uiHelper.onDestroy();
    }

    private void startPickerActivity(Uri data, int requestCode) {
         Intent intent = new Intent();
         intent.setData(data);
         intent.setClass(getActivity(), PickerActivity.class);
         startActivityForResult(intent, requestCode);
     }
}

选择器 Activity

public class PickerActivity extends FragmentActivity{

    public static final Uri FRIEND_PICKER = Uri.parse("picker://friend");

    private FriendPickerFragment friendPickerFragment;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pickers);

        Bundle args = getIntent().getExtras();
        FragmentManager manager = getSupportFragmentManager();
        Fragment fragmentToShow = null;
        Uri intentUri = getIntent().getData();

        if (FRIEND_PICKER.equals(intentUri)) {
            if (savedInstanceState == null) {
                friendPickerFragment = new FriendPickerFragment(args);
            } else {
                friendPickerFragment = 
                    (FriendPickerFragment) manager.findFragmentById(R.id.picker_fragment);
            }
            // Set the listener to handle errors
            friendPickerFragment.setOnErrorListener(new PickerFragment.OnErrorListener() {
                @Override
                public void onError(PickerFragment<?> fragment,
                                    FacebookException error) {
                    PickerActivity.this.onError(error);
                }
            });
            // Set the listener to handle button clicks
            friendPickerFragment.setOnDoneButtonClickedListener(
                    new PickerFragment.OnDoneButtonClickedListener() {
                @Override
                public void onDoneButtonClicked(PickerFragment<?> fragment) {
                    finishActivity();
                }
            });
            fragmentToShow = friendPickerFragment;

        } else {
            // Nothing to do, finish
            setResult(RESULT_CANCELED);
            finish();
            return;
        }

        manager.beginTransaction()
               .replace(R.id.picker_fragment, fragmentToShow)
               .commit();
    }

    private void onError(Exception error) {
        onError(error.getLocalizedMessage(), false);
    }

    private void onError(String error, final boolean finishActivity) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.error_dialog_title).
                setMessage(error).
                setPositiveButton(R.string.error_dialog_button_text, 
                   new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        if (finishActivity) {
                            finishActivity();
                        }
                    }
                });
        builder.show();
    }

    private void finishActivity() {
        setResult(RESULT_OK, null);
        finish();
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (FRIEND_PICKER.equals(getIntent().getData())) {
            try {
                friendPickerFragment.loadData(false);
            } catch (Exception ex) {
                onError(ex);
            }
        }
    }

}

编辑 logcat

01-05 13:36:45.560: D/GestureDetector(1733): [Surface Touch Event] mSweepDown False, mLRSDCnt : -1 mTouchCnt : 3 mFalseSizeCnt:0
01-05 13:36:45.710: D/ProgressBar(1733): setProgress = 0
01-05 13:36:45.710: D/ProgressBar(1733): setProgress = 0, fromUser = false
01-05 13:36:45.710: D/ProgressBar(1733): mProgress = 0mIndeterminate = false, mMin = 0, mMax = 100
01-05 13:36:45.740: D/AbsListView(1733): unregisterIRListener() is called 
01-05 13:36:45.760: D/ProgressBar(1733): updateDrawableBounds: left = 0
01-05 13:36:45.760: D/ProgressBar(1733): updateDrawableBounds: top = 3
01-05 13:36:45.760: D/ProgressBar(1733): updateDrawableBounds: right = 144
01-05 13:36:45.760: D/ProgressBar(1733): updateDrawableBounds: bottom = 147
01-05 13:36:45.890: D/AbsListView(1733): onVisibilityChanged() is called, visibility : 4
01-05 13:36:45.890: D/AbsListView(1733): unregisterIRListener() is called 
01-05 13:36:45.900: E/JavaBinder(1733): !!! FAILED BINDER TRANSACTION !!!
01-05 13:36:46.040: D/AbsListView(1733): onVisibilityChanged() is called, visibility : 0
01-05 13:36:46.040: D/AbsListView(1733): unregisterIRListener() is called 
01-05 13:36:46.040: D/AbsListView(1733): onVisibilityChanged() is called, visibility : 0
01-05 13:36:46.040: D/AbsListView(1733): unregisterIRListener() is called 
01-05 13:36:46.040: I/endeffect(1733): AbsListView.onMeasure(), getWidth()=0, getHeight()=0, this=android.widget.ListView{42460cc0 VFED.VC. .F....I. 0,0-0,0 #7f05006c app:id/selection_list}
01-05 13:36:46.070: D/dalvikvm(1733): GC_FOR_ALLOC freed 1056K, 11% free 19321K/21524K, paused 23ms, total 24ms
01-05 13:36:46.070: I/dalvikvm-heap(1733): Grow heap (frag case) to 20.170MB for 196828-byte allocation
01-05 13:36:46.090: D/dalvikvm(1733): GC_FOR_ALLOC freed 2K, 11% free 19510K/21720K, paused 20ms, total 20ms
01-05 13:36:46.140: D/dalvikvm(1733): GC_FOR_ALLOC freed 236K, 12% free 19448K/21880K, paused 22ms, total 22ms
01-05 13:36:46.140: I/dalvikvm-heap(1733): Grow heap (frag case) to 21.481MB for 1440016-byte allocation
01-05 13:36:46.170: D/dalvikvm(1733): GC_FOR_ALLOC freed <1K, 11% free 20854K/23288K, paused 29ms, total 29ms
01-05 13:36:46.180: D/AbsListView(1733): unregisterIRListener() is called 
01-05 13:36:46.180: I/endeffect(1733): AbsListView.onLayout(), getWidth()=960, getHeight()=240, this=android.widget.ListView{42460cc0 VFED.VC. .F....ID 60,270-1020,510 #7f05006c app:id/selection_list}
01-05 13:36:46.260: D/AbsListView(1733): unregisterIRListener() is called 

最佳答案

我终于解决了这个问题:

这只是一个权限问题。我所要做的就是在 SplashFragment.java 中添加这两行:

loginButton = (LoginButton) view.findViewById(R.id.login_button); 
loginButton.setReadPermissions("user_friends")

Facebook 出于安全原因更改了权限对话框,因此现在您必须向用户请求“user_friends” 权限才能访问好友列表。

我感到欣慰的是,这与 Failed Binder Transaction 无关,因为它仍然出现在我的应用程序中。我不知道这是否会以任何方式影响我的申请。很高兴知道它的作用。

关于android - Facebook 不显示好友列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27772916/

相关文章:

android - 如何在一些时间间隔后一个一个地动画多个对象android

java - 我可以在Processing中使用Android-Facebook SDK吗?

java - 从 Activity 的 Fragment 上的数组列表中删除项目

Javascript android 得到错误的宽度

error-handling - 验证访问 token 时出错

facebook - 使用 apache 和 tomcat 在同一台服务器上托管 facebook 应用程序和网站

javascript - 我可以更改网站中 Facebook 登录按钮的大小吗?

ios - 解析为 "Login with Facebook"的 FBLoginView

ios - 如何使用 Facebook 检索到的两个参数

android - Preferences .xml 文件应该放在哪里?