Android Facebook教程 - 用户为空

时间:2012-11-30 17:43:56

标签: android facebook facebook-android-sdk

我正在尝试面向Android开发人员的Facebook教程,我在步骤2 - Personalize遇到了问题

我尝试通过键入而不是复制和粘贴教程中的代码来学习,因此我可能输入错误的内容。我似乎无法找到它。

我的个人资料图片和用户名未显示,因为即使我已授权该应用,用户似乎仍为空。所以我的选择屏幕会显示,但它会显示一个空的用户配置文件。即使在上一个教程中,当我创建一个LoginFragment时,我的用户也没有在那里显示。有什么我做错了吗?

以下是我的完整代码减去import语句和类声明

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 Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
private static final String FRAGMENT_PREFIX = "fragment";

private static final String TAG = "MyFirstApp_FacebookMain.java";
private boolean isResumed = false;
private boolean restoredFragment = false;

private MenuItem settings;

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

    for(int i=0; i < fragments.length; i++) {
        restoreFragment(savedInstanceState, i);
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    FragmentManager manager = getSupportFragmentManager();

    // Since we are only adding one fragment at a time, we can only save one.
    Fragment f = manager.findFragmentById(R.id.body_frame);
    for(int i=0; i < fragments.length; i++) {
        if(fragments[i] == f) {
            manager.putFragment(outState, getBundleKey(i), fragments[i]);
        }
    }
}

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

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

@Override
protected void onSessionStateChange(SessionState state, Exception exception) {
    if(isResumed) {
        FragmentManager manager = getSupportFragmentManager();
        int backStackSize = manager.getBackStackEntryCount();
        for(int i=0; i < backStackSize; i++) {
            manager.popBackStack();
        }
        if(state.isOpened()) {
            FragmentTransaction transaction = manager.beginTransaction();
            transaction.replace(R.id.body_frame, fragments[SELECTION]).commit();
        } else if (state.isClosed()) {
            FragmentTransaction transaction = manager.beginTransaction();
            transaction.replace(R.id.body_frame, fragments[SPLASH]).commit();
        }
    }
}

@Override
protected void onResumeFragments() {
    super.onResumeFragments();
    Session session = Session.getActiveSession();
    if (session == null || session.getState().isClosed()) {
        session = new Session(this);
        Session.setActiveSession(session);
    }

    FragmentManager manager = getSupportFragmentManager();

    if (restoredFragment) {
        return;
    }

    // If we already have a valid token, then we can just open the session silently,
    // otherwise present the splash screen and ask the user to login.
    if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
        // no need to add any fragments here since it will be 
        // handled in onSessionStateChange
        session.openForRead(this);
    } else if (session.isOpened()) {
        // if the session is already open, try to show the selection fragment
        Fragment fragment = manager.findFragmentById(R.id.body_frame);
        if (!(fragment instanceof SelectionFragment)) {
            manager.beginTransaction().replace(R.id.body_frame, 
                    fragments[SELECTION]).commit();
        }
    } else {
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.replace(R.id.body_frame, 
              fragments[SPLASH]).commit();
    }
}

private String getBundleKey(int index) {
    return FRAGMENT_PREFIX + Integer.toString(index);
}

private void restoreFragment(Bundle savedInstanceState, int fragmentIndex) {
    Fragment fragment = null;
    if(savedInstanceState != null) {
        FragmentManager manager = getSupportFragmentManager();
        fragment = manager.getFragment(savedInstanceState, getBundleKey(fragmentIndex));
    }
    if(fragment != null) {
        fragments[fragmentIndex] = fragment;
        restoredFragment = true;
    } else {
        switch(fragmentIndex) {
            case SPLASH:
                fragments[SPLASH] = new SplashFragment();
                break;
            case SELECTION:
                fragments[SELECTION] = new SelectionFragment();
                break;
            case SETTINGS:
                fragments[SETTINGS] = new LoginFragment();
                break;
            default:
                Log.w(TAG, "invalid fragment index");
                break;
        }
    }
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    FragmentManager manager = getSupportFragmentManager();
    Fragment currentFragment = manager.findFragmentById(R.id.body_frame);
    // only add the menu when the selection fragment is showing
    if (currentFragment == fragments[SELECTION]) {
        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)) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.add(R.id.body_frame, fragments[SETTINGS]).addToBackStack(null).commit();
        return true;
    }
    return false;
}

和SelectionFragment.java

public class SelectionFragment extends Fragment {
private ProfilePictureView profilePictureView;
private TextView userNameView;

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

    // Get the active session
    final Session session = Session.getActiveSession();
    if (session != null && session.isOpened()) {
        // if the session is open, make an API call to get user data
        // and define a 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 userid for the ProfilePictureView
                        // view that in turn displays the profile picture
                        profilePictureView.setProfileId(user.getId());
                        // set the textview to the user's name
                        userNameView.setText(user.getName());
                    }
                }
            }
        });
        Request.executeBatchAsync(request);
    }
    return view;
}
}

最后是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;
}
}

4 个答案:

答案 0 :(得分:5)

user1258600,我有同样的问题,我解决了!!

您的代码没有问题......

您在Android Manifest中错过了INTERNET权限!

尝试添加

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

到你的Android清单上,你会没事的!

为了解决这个问题,我进入了声明,我发现用户为空,我打印出错误,这表明我将INTERNET权限添加到我的Android清单。

@Override
public void onCompleted(GraphUser user, Response response) {
// If the response is successful
    if (session == Session.getActiveSession()) {
    System.out.println("user: " + user);
                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!!
                System.out.println("response error: " + response.getError());
            }
        }

答案 1 :(得分:1)

使用此代码登录facebook

mFacebook = new Facebook(APP_ID);
SessionStore.restore(mFacebook, getApplicationContext());
mAsyncRunner = new AsyncFacebookRunner(mFacebook);

这个使用此功能来获取个人资料图片注意根据您的需要修改它:)

void update_user_image() {
    Bundle params = new Bundle();
    params.putString("fields", "id,picture");
    mAsyncRunner.request("me", params, new AsyncRequestListener(this) {

        @Override
        public void onComplete(JSONObject obj, Object state) {
            try {
                String Image_url = obj.optString("picture");
                if (Image_url.contains("_q.jpg"))
                    Image_url = Image_url.replace("_q.jpg", "_n.jpg");
                if (Image_url.contains("_s.jpg"))
                    Image_url = Image_url.replace("_s.jpg", "_n.jpg");
                if (userImage != null && userImage.getImageUrl() != null)
                    if (!userImage.getImageUrl().equals(Image_url)) {
                        Editor editor = mActivity.getSharedPreferences("userInformation", Context.MODE_PRIVATE).edit();
                        editor.putString("ImageURL", Image_url);
                        editor.commit();
                        final String latest_image_url = Image_url;
                        main.this.runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                userImage.setImageUrl(latest_image_url);                                
                                userImage.loadImage();

                            }
                        });
                    }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

答案 2 :(得分:1)

出于绝望,我重新启动了整个项目,现在就可以了。我想我永远不会发现出了什么问题。 :(

答案 3 :(得分:1)

作为satoukum帖子的后续内容,请确保将INTERNET权限标记放在<application>标记的外部。对于经验丰富的Android开发人员而言,这可能不是一件容易的事,但Facebook文档并未明确指出此标记不应位于<application>标记内

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.blah.blah" >

 <uses-permission android:name="android.permission.INTERNET"/>

<application>
</application>

</manifest>