使用 Facebook SDK 4.0 进行 Android 登录
Posted
技术标签:
【中文标题】使用 Facebook SDK 4.0 进行 Android 登录【英文标题】:Android Login with Facebook SDK 4.0 【发布时间】:2015-06-04 04:04:42 【问题描述】:我希望有人可以帮助我!我想为新的 facebook sdk 4.0 更改我的代码,但只有一点描述,我快疯了,不知道如何使用 facebook 登录按钮和 accesstoken 制作新代码
此代码的目标是用户使用他的 facebook 帐户登录并检查用户是否已经退出。如果没有,则插入带有电子邮件和 facebook id 和名称的新用户
我已将代码标记为 //needs to be changed 和 //needs to be changed END
提前感谢您的帮助!!!
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
// import com.facebook.Request;
//import com.facebook.Request.GraphUserCallback;
// import com.facebook.Response;
// import com.facebook.Session;
// import com.facebook.SessionState;
//import com.facebook.UiLifecycleHelper;
// import com.facebook.model.GraphUser;
// import com.facebook.widget.LoginButton;
@SuppressLint("NewApi")
public class AuthenticationFragment extends Fragment
LoginButton facebookLoginButton;
// private UiLifecycleHelper uiHelper;
String TAG = "Fragment";
Button btnLogin, btnCreateAccount;
ProgressDialog dialogPrg;
String userName = null;
// New Facebook Added
CallbackManager callbackManager;
public static final AuthenticationFragment newInstance()
// TODO Auto-generated constructor stub
AuthenticationFragment fragment = new AuthenticationFragment();
return fragment;
@Override
public void onAttach(Activity activity)
// TODO Auto-generated method stub
super.onAttach(activity);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.authentication_layout, container,
false);
facebookLoginButton = (LoginButton) view
.findViewById(R.id.btnFacebookLogin);
facebookLoginButton.setFragment(this);
facebookLoginButton.setReadPermissions(Arrays.asList("email"));
// New added for Facebook
// Callback registration
facebookLoginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>()
@Override
public void onSuccess(LoginResult loginResult)
// App code
//login ok get access token
AccessToken.getCurrentAccessToken();
@Override
public void onCancel()
// App code
Log.i(TAG, "facebook login canceled");
@Override
public void onError(FacebookException exception)
// App code
Log.i(TAG, "facebook login failed error");
);
//New added for Facebook END
btnLogin = (Button) view.findViewById(R.id.btn_login);
btnCreateAccount = (Button) view.findViewById(R.id.btn_create_account);
btnLogin.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Intent intent = new Intent(getActivity(), LoginActivity.class);
startActivity(intent);
);
btnCreateAccount.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
// TODO Auto-generated method stub
Intent intent = new Intent(getActivity(),
CreateAccountActivity.class);
startActivity(intent);
);
dialogPrg = new ProgressDialog(getActivity());
dialogPrg.setCanceledOnTouchOutside(false);
return view;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
// uiHelper = new UiLifecycleHelper(getActivity(), callback);
// uiHelper.onCreate(savedInstanceState);
// Needs to be changed
private Session.StatusCallback callback = new Session.StatusCallback()
@Override
public void call(final Session session, final SessionState state,
final Exception exception)
onSessionStateChange(session, state, exception);
;
// Needs to be changed END
private void onSessionStateChange(Session session, SessionState state,
Exception exception)
if (state.isOpened())
Log.i("FB AUT FRAGMENT", "Logged in...");
else if (state.isClosed())
Log.i("FB AUT FRAGMENT", "Logged out...");
// Needs to be changed
private void insertUser(Session session)
Request.newMeRequest(session, new GraphUserCallback()
@Override
public void onCompleted(GraphUser user, Response response)
// TODO Auto-generated method stub
new facebookUserCheck(user).start();
).executeAsync();
// Needs to be changed END
// Needs to be changed
private class facebookUserCheck extends Thread
GraphUser user;
public facebookUserCheck(GraphUser user)
// TODO Auto-generated constructor stub
this.user = user;
// Needs to be changed
@Override
public void run()
// TODO Auto-generated method stub
super.run();
// TODO Auto-generated method stub
String handleInsertUser = getActivity().getResources().getString(
R.string.users_json_url)
+ "facebook_user_check";
try
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(handleInsertUser);
MultipartEntity reqEntity = new MultipartEntity();
// Needs to be changed user.getId
reqEntity.addPart("fb_id", new StringBody(user.getId()));
// Needs to be changed END
post.setEntity(reqEntity);
HttpResponse res = client.execute(post);
HttpEntity resEntity = res.getEntity();
final String response_str = EntityUtils.toString(resEntity);
if (resEntity != null)
Log.i(TAG, response_str);
getActivity().runOnUiThread(new Runnable()
public void run()
try
dialogPrg.dismiss();
JSONArray jsonArray = new JSONArray(
response_str);
if (jsonArray.length() == 1)
JSONObject obj = jsonArray.getJSONObject(0);
User user = Ultils.parseUser(obj);
UserSessionManager userSession = new UserSessionManager(
getActivity());
userSession.storeUserSession(user);
Intent intent = new Intent(getActivity(),
HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
catch (Exception e)
LayoutInflater inflater = LayoutInflater
.from(getActivity());
View promptsView = inflater.inflate(
R.layout.username_promtps_layout, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
getActivity());
// set prompts.xml to alertdialog builder
alertDialogBuilder.setView(promptsView);
final EditText message = (EditText) promptsView
.findViewById(R.id.editTextDialogUserInput);
alertDialogBuilder
.setMessage(getResources().getString(
R.string.choose_your_user_name));
// set dialog message
alertDialogBuilder
.setCancelable(false)
.setPositiveButton(
getResources().getString(
R.string.ok_label),
new DialogInterface.OnClickListener()
public void onClick(
DialogInterface dialog,
int id)
if (!Validator
.validUserName(message
.getText()
.toString()))
showDialog(getResources()
.getString(
R.string.invalid_user_name));
return;
userName = message
.getText()
.toString();
new facebookUserRegister(
user).start();
);
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder
.create();
// show it
alertDialog.show();
);
catch (Exception e)
// TODO: handle exception
e.printStackTrace();
// Needs to be changed
private class facebookUserRegister extends Thread
GraphUser user;
public facebookUserRegister(GraphUser user)
// TODO Auto-generated constructor stub
this.user = user;
// Needs to be changed END
@Override
public void run()
super.run();
getActivity().runOnUiThread(new Runnable()
@Override
public void run()
// TODO Auto-generated method stub
dialogPrg.show();
);
String handleInsertUser = getActivity().getResources().getString(
R.string.users_json_url)
+ "facebook_user_register";
try
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(handleInsertUser);
MultipartEntity reqEntity = new MultipartEntity();
// Needs to be changed user.getId, user.getName, user.asMap
reqEntity.addPart("fb_id", new StringBody(user.getId()));
reqEntity.addPart("fullname", new StringBody(user.getName()));
reqEntity.addPart("email", new StringBody(user.asMap().get("email").toString()));
// Needs to be changed END
reqEntity.addPart("username", new StringBody(userName));
post.setEntity(reqEntity);
HttpResponse res = client.execute(post);
HttpEntity resEntity = res.getEntity();
final String response_str = EntityUtils.toString(resEntity);
if (resEntity != null)
Log.i(TAG, response_str);
getActivity().runOnUiThread(new Runnable()
public void run()
try
dialogPrg.dismiss();
JSONObject jsonObj = new JSONObject(
response_str);
if (jsonObj.getString("ok").equals("0"))
// show error email;
showDialog(getActivity().getResources()
.getString(R.string.email_exist));
return;
if (jsonObj.getString("ok").equals("1"))
// show error username
showDialog(getActivity()
.getResources()
.getString(R.string.user_name_exist));
return;
if (jsonObj.getString("ok").equals("2"))
// show unknow username
showDialog(getActivity().getResources()
.getString(R.string.login_failed));
return;
catch (Exception e)
JSONArray jsonArray;
try
jsonArray = new JSONArray(response_str);
if (jsonArray.length() == 1)
JSONObject obj = jsonArray
.getJSONObject(0);
User user = Ultils.parseUser(obj);
UserSessionManager userSession = new UserSessionManager(
getActivity());
userSession.storeUserSession(user);
Intent intent = new Intent(
getActivity(),
HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
catch (JSONException e1)
// TODO Auto-generated catch block
e1.printStackTrace();
showDialog(getActivity().getResources()
.getString(R.string.login_failed));
);
catch (Exception e)
// TODO: handle exception
e.printStackTrace();
// Needs to be changed
@Override
public void onResume()
super.onResume();
Session session = Session.getActiveSession();
if (session != null && (session.isOpened() || session.isClosed()))
onSessionStateChange(session, session.getState(), null);
// uiHelper.onResume();
// Needs to be changed END
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
// New Facebook added
callbackManager.onActivityResult(requestCode, resultCode, data);
//New Facebook added END
// uiHelper.onActivityResult(requestCode, resultCode, data);
// Needs to be changed
if (Session.getActiveSession() != null
&& Session.getActiveSession().isOpened())
dialogPrg.setMessage(getActivity().getResources().getString(
R.string.loging));
dialogPrg.show();
facebookLoginButton.setEnabled(false);
insertUser(Session.getActiveSession());
// Needs to be changed END
@Override
public void onPause()
super.onPause();
// uiHelper.onPause();
@Override
public void onDestroy()
super.onDestroy();
// uiHelper.onDestroy();
@Override
public void onSaveInstanceState(Bundle outState)
super.onSaveInstanceState(outState);
// uiHelper.onSaveInstanceState(outState);
public void showDialog(String message)
Ultils.logout(getActivity());
AlertDialog.Builder buidler = new AlertDialog.Builder(getActivity());
buidler.setMessage(message);
buidler.setPositiveButton(
getActivity().getResources().getString(R.string.ok_label),
new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
// TODO Auto-generated method
// stub
facebookLoginButton.setEnabled(true);
);
AlertDialog dialog = buidler.create();
dialog.show();
【问题讨论】:
您似乎从未使用实际实例初始化您的 callbackManager。您应该尝试添加 callbackManager = CallbackManager.Factory.create();在你的 onCreateView 中,就在你调用 facebookLoginButton.registerCallback 之前。 嗨,是的,到目前为止,我已将其放入 AuthenticationActivity ....但对我而言,如何更改代码以再次使用 facebook sdk 4.0 很重要 你在AuthenticationActivity中放了什么? callbackManager 的初始化?你能在那里显示代码吗?这是实际获得登录结果的关键部分。 如果放了这段代码,但认为这可能是错误的!应该将它移动到片段中的 CreateView @Override protected void onCreate(Bundle savedInstanceState) // TODO 自动生成的方法存根 super.onCreate(savedInstanceState); FacebookSdk.sdkInitialize(getApplicationContext()); callbackManager = CallbackManager.Factory.create(); setContentView(R.layout.frame_layout); 将 callbackManager 初始化移动到您的 Fragment 代码中。还要在 onActivityResult 中放置一个断点,并确保在登录完成时调用它。 【参考方案1】:使用此代码段登录 Facebook。在我的应用中就像一个魅力。
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import com.facebook.AppEventsLogger;
import com.facebook.FacebookAuthorizationException;
import com.facebook.FacebookOperationCanceledException;
import com.facebook.FacebookRequestError;
import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphObject;
import com.facebook.model.Graphplace;
import com.facebook.model.GraphUser;
import com.facebook.widget.FacebookDialog;
import com.facebook.widget.LoginButton;
import com.facebook.widget.ProfilePictureView;
import com.ids.service.R;
import android.support.v4.app.FragmentActivity;
import android.app.AlertDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends FragmentActivity
private final String PENDING_ACTION_BUNDLE_KEY = "com.facebook.samples.hellofacebook:PendingAction";
private LoginButton loginButton;
private ProfilePictureView profilePictureView;
private PendingAction pendingAction = PendingAction.NONE;
private GraphUser user;
private GraphPlace place;
private List<GraphUser> tags;
private boolean canPresentShareDialog;
private boolean canPresentShareDialogWithPhotos;
private enum PendingAction
NONE,
POST_PHOTO,
POST_STATUS_UPDATE
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback()
@Override
public void call(Session session, SessionState state,
Exception exception)
onSessionStateChange(session, state, exception);
;
private FacebookDialog.Callback dialogCallback = new FacebookDialog.Callback()
@Override
public void onError(FacebookDialog.PendingCall pendingCall, Exception error, Bundle data)
Log.d("Facebook", String.format("Error: %s", error.toString()));
@Override
public void onComplete(FacebookDialog.PendingCall pendingCall, Bundle data)
Log.d("Facebook", "Success!");
;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
if (savedInstanceState != null)
String name = savedInstanceState.getString(PENDING_ACTION_BUNDLE_KEY);
pendingAction = PendingAction.valueOf(name);
setContentView(R.layout.activity_main);
profilePictureView = (ProfilePictureView) findViewById(R.id.profilePicture);
loginButton = (LoginButton) findViewById(R.id.login_button);
loginButton.setUserInfoChangedCallback(new LoginButton.UserInfoChangedCallback()
@Override
public void onUserInfoFetched(GraphUser user)
MainActivity.this.user = user;
updateUI();
// It's possible that we were waiting for this.user to be populated in order to post a
// status update.
handlePendingAction();
);
@Override
protected void onResume()
super.onResume();
uiHelper.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);
updateUI();
@Override
protected void onSaveInstanceState(Bundle outState)
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
outState.putString(PENDING_ACTION_BUNDLE_KEY, pendingAction.name());
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data, dialogCallback);
@Override
public void onPause()
super.onPause();
uiHelper.onPause();
// Call the 'deactivateApp' method to log an app event for use in analytics and advertising
// reporting. Do so in the onPause methods of the primary Activities that an app may be launched into.
AppEventsLogger.deactivateApp(this);
@Override
public void onDestroy()
super.onDestroy();
uiHelper.onDestroy();
private void onSessionStateChange(Session session, SessionState state, Exception exception)
if (pendingAction != PendingAction.NONE &&
(exception instanceof FacebookOperationCanceledException ||
exception instanceof FacebookAuthorizationException))
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.cancelled)
.setMessage(R.string.permission_not_granted)
.setPositiveButton(R.string.ok, null)
.show();
pendingAction = PendingAction.NONE;
else if (state == SessionState.OPENED_TOKEN_UPDATED)
handlePendingAction();
updateUI();
@SuppressWarnings("unused")
private void updateUI()
Session session = Session.getActiveSession();
if (user != null)
profilePictureView.setProfileId(user.getId());
Log.e("Name", user.getName());
@SuppressWarnings("incomplete-switch")
private void handlePendingAction()
PendingAction previouslyPendingAction = pendingAction;
// These actions may re-set pendingAction if they are still pending, but we assume they
// will succeed.
pendingAction = PendingAction.NONE;
switch (previouslyPendingAction)
case POST_PHOTO:
postPhoto();
break;
case POST_STATUS_UPDATE:
postStatusUpdate();
break;
private interface GraphObjectWithId extends GraphObject
String getId();
private void showPublishResult(String message, GraphObject result, FacebookRequestError error)
String title = null;
String alertMessage = null;
if (error == null)
title = getString(R.string.success);
String id = result.cast(GraphObjectWithId.class).getId();
alertMessage = getString(R.string.successfully_posted_post, message, id);
else
title = getString(R.string.error);
alertMessage = error.getErrorMessage();
new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(alertMessage)
.setPositiveButton(R.string.ok, null)
.show();
private FacebookDialog.ShareDialogBuilder createShareDialogBuilderForLink()
return new FacebookDialog.ShareDialogBuilder(this)
.setName("Hello Facebook")
.setDescription("The 'Hello Facebook' sample application showcases simple Facebook integration")
.setLink("http://developers.facebook.com/android");
private void postStatusUpdate()
if (canPresentShareDialog)
FacebookDialog shareDialog = createShareDialogBuilderForLink().build();
uiHelper.trackPendingDialogCall(shareDialog.present());
else if (user != null && hasPublishPermission())
final String message = getString(R.string.status_update, user.getFirstName(), (new Date().toString()));
Request request = Request
.newStatusUpdateRequest(Session.getActiveSession(), message, place, tags, new Request.Callback()
@Override
public void onCompleted(Response response)
showPublishResult(message, response.getGraphObject(), response.getError());
);
request.executeAsync();
else
pendingAction = PendingAction.POST_STATUS_UPDATE;
private FacebookDialog.PhotoShareDialogBuilder createShareDialogBuilderForPhoto(Bitmap... photos)
return new FacebookDialog.PhotoShareDialogBuilder(this)
.addPhotos(Arrays.asList(photos));
private void postPhoto()
Bitmap image = BitmapFactory.decodeResource(this.getResources(), R.drawable.ic_launcher);
if (canPresentShareDialogWithPhotos)
FacebookDialog shareDialog = createShareDialogBuilderForPhoto(image).build();
uiHelper.trackPendingDialogCall(shareDialog.present());
else if (hasPublishPermission())
Request request = Request.newUploadPhotoRequest(Session.getActiveSession(), image, new Request.Callback()
@Override
public void onCompleted(Response response)
showPublishResult(getString(R.string.photo_post), response.getGraphObject(), response.getError());
);
request.executeAsync();
else
pendingAction = PendingAction.POST_PHOTO;
private boolean hasPublishPermission()
Session session = Session.getActiveSession();
return session != null && session.getPermissions().contains("publish_actions");
【讨论】:
您好,谢谢您回答 Varun,但我的代码也运行良好。可能是误会!我想更改代码以兼容新的 facebook sdk 4.0【参考方案2】:正如您在Facebook SDK for Android changelog in section 4.0 - March 25, 2015 中看到的那样,UiLifecycleHelper 已被删除,其功能已转移到 CallbackManager。
Here 是一个教程,它解释了如何使用 facebook SDK 4.0 实现登录。
【讨论】:
以上是关于使用 Facebook SDK 4.0 进行 Android 登录的主要内容,如果未能解决你的问题,请参考以下文章
如何解决这个 Facebook SDK 4.0 登录按钮异常
ParseFacebookUtilsV4 和 Facebook-iOS-SDK 4.0
Android Facebook SDK 4.0 登录:用户登录 Facebook 应用程序时出错
Facebook PHP SDK 4.0 使用 Lumen 登录
任何示例显示如何使用自己的按钮或 Facebook 按钮在 Android 中使用 Facebook SDK 4.0 登录?