我正在尝试面向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;
}
}
答案 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>