使用 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 登录

iOS Facebook sdk 4.0 分享图片

任何示例显示如何使用自己的按钮或 Facebook 按钮在 Android 中使用 Facebook SDK 4.0 登录?