我正在关注Facebook SDK Scrumptious教程。我成功完成了登录和个性化步骤。现在我被困在Show Me步骤。
当我点击选择朋友时,朋友列表为空。
我添加了我的兄弟作为应用程序的测试人员,他点击了他的Facebook开发者页面中的接受。然后,在Eclipse上,我在他的手机上运行了应用程序。但当他点击选择朋友时,它仍然是空的。它没有显示我的名字。当我在手机上运行应用程序时,我没有在朋友列表中看到他的名字。
有人知道为什么我在朋友名单上看不到他的名字吗? 该应用程序适用于我们的手机,但朋友列表是空的。
我一步一步地按照教程。
我相信我正在使用正确的哈希键,因为我们的手机上都会打开应用程序。我应该实施一些新的东西吗?Facebook还没有更新他们的教程?
Eclipse存在问题吗?
MainActivity.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);
}
}
}
SplashFragment.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;
}
}
SelectionFragment.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);
}
}
PickerActivity
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
答案 0 :(得分:1)
我终于解决了这个问题:
这只是一个权限问题。我只需要在SplashFragment.java
中添加这两行:
loginButton = (LoginButton) view.findViewById(R.id.login_button);
loginButton.setReadPermissions("user_friends")
Facebook出于安全原因更改了权限对话框,因此现在您必须要求用户"user_friends"
权限才能访问好友列表。
我感到宽慰的是,这与Failed Binder Transaction
无关,因为这仍然出现在我的应用程序中。我不知道这是否会以任何方式影响我的申请。很高兴知道它的作用。