最近公司要写集成登陆SDK,具体集成那些我就不说了,其中就包含需要使用facebook登陆自己的app,于是我苦心研究facebook,写完后发现各种问题,对于问题我当然去查阅官方文档看怎么解决,结果一查,我的天,SDK更新了,以前是两种方式loginButton和UserSettingsFragment,而对于两种方式来说都不适合我,因为我要写sdk供别人使用,所以别人要用那种登陆按钮需要用户自己定义,而不是用facebook自己的。对于两种方式来说,由于第二种不需要开发者参与,布局按钮都是facebook提供的,所以我采用参考第一种。现在facebook更新了,第一种还是loginbutton,但是调用方法步骤上不同了,而第二种变为loginManager了,今天我还是采用第一种详细介绍如何使用facebook实现第三方登陆。
1,我们先看看使用前需要做什么:具体步骤可以参考官方文档:https://developers.facebook.com/docs/androidlocale=zh_CN,(下载SDK)
https://developers.facebook.com/docs/android?locale=zh_CN#!/docs/android/getting-started/
1点击页面的quick start for android 然后输入框输入你要创建的应用名称 然后下载sdk
2安装facebook应用(装不装其实取决于自己,装上登陆的时候会跳到应用的登陆界面,不装会跳转到webview的登陆界面)
3.引入sdk.官方用的是android studio.我用的是eclipse.导入sdk,作为引用库引入。不会的可以自己百度
4填写你应用的包名和默认启动的activity
5添加Key Hashes,Key
Hashes分为开发和发布两种。具体生成方法请看下面
首先你需要安装openssl,不然你是无法生成的,装了cygwin的也可以
windows执行下面的命令:先要进入ssl的安装目录
keytool
-exportcert -alias androiddebugkey -keystore debugkey的路径 | openssl sha1 -binary | openssl
base64
mac执行下面的命令:
keytool
-exportcert -alias androiddebugkey -keystore
debugkey的路径 | openssl sha1 -binary | openssl base64
发布版的替换为自己的证书路径,如果不会可以百度搜索,因为重点不是将这个,所以需要的可以自行百度
6跟踪app打开和安装,直接可以过,如果需要做用户行为记录的可以阅读一下。
7完成。
做完上面的准备,我们就可以开始了,至于appid,可以登陆facebook账号在刚才建立的应用名字哪里就可以看到
如果需要验证是否成功,可以在刚才设置的那个activiy里加上这段代码,运行后可以打印出你设置的key hashes
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Add code to print out the key hash try { PackageInfo info = getPackageManager().getPackageInfo( "com.facebook.samples.hellofacebook", PackageManager.GET_SIGNATURES); for (Signature signature : info.signatures) { MessageDigest md = MessageDigest.getInstance("SHA"); md.update(signature.toByteArray()); Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT)); } } catch (NameNotFoundException e) { } catch (NoSuchAlgorithmException e) { } ...
接下来我们看官方的指引
Facebook Login for Android
The Facebook SDK for Android enables people to sign into your app with Facebook Login. When people log into your app with Facebook they can grant permissions to your app so you can retrieve information or perform actions on Facebook on their behalf.
To read more Facebook login and why use it, see Login Portal.
There are two ways to implement Facebook login on Android:
LoginButton
class - Which provides a button you can add to your UI. It follows the current access token and can log people in
and out.LoginManager
class - To initiate login without using a UI element.
For information on permissions, see Managing Permissions, Android.
大概意思是说实现使用facebook登陆的两种实现方式
Prerequisites
Before you implement Facebook Login you need:
- Facebook App - Configured and linked to your app, with Single Sign On enabled.
- Facebook SDK - Added to your project, see Getting Started, Facebook Android
SDK. - Facebook App ID - Configure and link this to your Android app. See Android
Getting Started, Add Facebook App ID - Android Key Hash - Generate this and add it to your developer
profile Facebook
- Include this in
ActivityAndroidManifest.xml
意思是说要实现功能,上面列出的是必要条件
Add Facebook Login
The simplest way to add Facebook Login to your app is to add LoginButton
from the SDK. This is a custom view implementation of a Button
.
You can use this button in your app to implement Facebook Login.
There are other classes you use to add login to your app. The SDK includes:
- LoginManager - Initiates the login process with the requested read or publish permissions.
- LoginButton: - This UI element wraps functionality available in the
LoginManager
. So when someone clicks on
the button, the login is initiated with the set permissions. The button follows the login state, and displays the correct text based on someone‘s authentication state. - CallbackManager - Use to route calls back to the Facebook SDK and your registered callbacks. You should call it from the initiating activity or fragments
onActivityResult
call. - AccessToken: - Use this class Graph API requests. It shows the user id, and the accepted and denied permissions.
- Profile - This class has basic information about person logged in.
https://developers.facebook.com/docs/facebook-login/android/v2.3
package com.tibco.integration.login.facebook; import java.util.Arrays; import java.util.List; import org.json.JSONObject; import android.app.Activity; import android.content.Intent; import android.view.View; import com.facebook.AccessToken; import com.facebook.CallbackManager; import com.facebook.FacebookCallback; import com.facebook.FacebookException; import com.facebook.FacebookSdk; import com.facebook.GraphRequest; import com.facebook.GraphResponse; import com.facebook.ProfileTracker; import com.facebook.login.LoginManager; import com.facebook.login.LoginResult; import com.tibco.integeration.login.listener.LogInStateListener; import com.tibco.integeration.login.listener.LogOutStateListener; import com.tibco.integration.login.model.User; public class FaceBookLoginUtil{ private static FaceBookLoginUtil mFaceBookLoginUtil=null; private static Activity loginActivity=null; private View loginClickView=null; private View logOutView=null; private List<String> permissions; private LogInStateListener mBookLoginStateChanged; private LogOutStateListener mBookLogOutStateListener; private CallbackManager callbackManager; private FaceBookCallBackListener callback=new FaceBookCallBackListener(); private OnFaceBookLoginClickListener onFaceBookLoginClickListener=new OnFaceBookLoginClickListener(); private boolean isLogOut=false; public static FaceBookLoginUtil getInstance() { if(mFaceBookLoginUtil==null){ mFaceBookLoginUtil=new FaceBookLoginUtil(); } return mFaceBookLoginUtil; } public void SetFaceBookLoginActivity(Activity activity){ if(activity==null){ throw new NullPointerException("login activity is null"); }else{ loginActivity=activity; } } public void SetFaceBookLoginButton(View view){ loginClickView=view; } public void SetFaceBookLogOutButton(View view){ logOutView=view; } public void SetFaceBookReadPermission(String array){ if(array==null){ permissions=Arrays.asList("public_profile"); }else{ permissions=Arrays.asList(array); } } public void SetOnFaceBookLoginStateListener(LogInStateListener LoginStateChanged){ if(LoginStateChanged==null){ throw new NullPointerException("LoginStateListener is null"); }else{ mBookLoginStateChanged=LoginStateChanged; } } public void SetOnFaceBookLogOutListener(LogOutStateListener logoutListener){ mBookLogOutStateListener=logoutListener; } public void open() { FacebookSdk.sdkInitialize(loginActivity); callbackManager = CallbackManager.Factory.create(); LoginManager.getInstance().registerCallback(callbackManager, callback); if(loginClickView!=null){ loginClickView.setOnClickListener(onFaceBookLoginClickListener); } if(logOutView!=null){ logOutView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LoginManager.getInstance().logOut(); isLogOut=true; mBookLogOutStateListener.OnLogOutListener(isLogOut,"facebook"); } }); } } public void onActivityResult(int requestCode, int resultCode, Intent data) { callbackManager.onActivityResult(requestCode, resultCode, data); } public void OnDestory(){ profileTracker.stopTracking(); } private class FaceBookCallBackListener implements FacebookCallback<LoginResult>{ @Override public void onSuccess(LoginResult result) { fetchUserInfo(result.getAccessToken()); } @Override public void onCancel() { mBookLoginStateChanged.OnLoginError("user cancle log in facebook!"); } @Override public void onError(FacebookException error) { mBookLoginStateChanged.OnLoginError(error.getMessage()); } } private class OnFaceBookLoginClickListener implements View.OnClickListener{ @Override public void onClick(View v) { LoginManager.getInstance().logInWithReadPermissions(loginActivity,permissions); } } private void fetchUserInfo(AccessToken accessToken){ GraphRequest request = GraphRequest.newMeRequest( accessToken, new GraphRequest.GraphJSONObjectCallback() { @Override public void onCompleted(JSONObject object, GraphResponse response) { try{ if(response.getError()!=null){ mBookLoginStateChanged.OnLoginError(<span style="font-family: Arial, Helvetica, sans-serif;">response.getError()..getErrorMessage()</span>); }else if(response.getConnection().getResponseCode()==200){ User user=new User(); user.setEmail(object.getString("email")); user.setGender(object.getString("gender")); user.setLink(object.getString("link")); user.setFirstname(object.getString("first_name")); user.setLastname(object.getString("last_name")); user.setLocale(object.getString("locale")); user.setTimezone(object.getString("timezone")); user.setUserId(object.getString("id")); user.setUserName(object.getString("name")); mBookLoginStateChanged.OnLoginSuccess(user, "facebook"); } }catch(Exception e){ mBookLoginStateChanged.OnLoginError(e.getMessage()); } } }); request.executeAsync(); } }
package com.tibco.integration.login.model; import java.io.Serializable; import android.net.Uri; public class User implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String status; private String error_message; private String email; private String token; private String firstname; private String lastname; private String userId; private String tibbrUserId; private String userName; private String middleName; private String link; private String birthday; private String ProfilePictureUri; private String gender; private String locale; private String timezone; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getError_message() { return error_message; } public void setError_message(String error_message) { this.error_message = error_message; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getTibbrUserId() { return tibbrUserId; } public void setTibbrUserId(String tibbrUserId) { this.tibbrUserId = tibbrUserId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getMiddleName() { return middleName; } public void setMiddleName(String middleName) { this.middleName = middleName; } public String getLink() { return link; } public void setLink(String link) { this.link = link; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public String getProfilePictureUri() { return ProfilePictureUri; } public void setProfilePictureUri(String profilePictureUri) { ProfilePictureUri = profilePictureUri; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getLocale() { return locale; } public void setLocale(String locale) { this.locale = locale; } public String getTimezone() { return timezone; } public void setTimezone(String timezone) { this.timezone = timezone; } }
有了登陆工具类和用户类,接下来就是再次封装了 <pre name="code" class="java">package com.tibco.integration.login.utils; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.view.View; import com.tibco.integeration.login.listener.LogInStateListener; import com.tibco.integeration.login.listener.LogOutStateListener; import com.tibco.integration.login.facebook.FaceBookLoginUtil; import com.tibco.integration.login.tibbr.TibbrLoginUtil; public class LoginManager { private static FaceBookLoginUtil fbUtil=null; private static TibbrLoginUtil tbutils=null; /** * 登陆工具类, * */ public static void initialize(Context context){ fbUtil=FaceBookLoginUtil.getInstance(); tbutils=TibbrLoginUtil.getInstance(); } /** * 1 if you use facebook account login,you must call this method and set params. * @param activity * @param loginButton * @param arrarPermission * @param savedInstanceState * @param loginstateListener */ public static void setFaceBookLoginParams(Activity activity,View loginButton,String arrarPermission,LogInStateListener loginstateListener){ fbUtil.SetFaceBookLoginActivity(activity); fbUtil.SetFaceBookLoginButton(loginButton); fbUtil.SetFaceBookReadPermission(arrarPermission); fbUtil.SetOnFaceBookLoginStateListener(loginstateListener); fbUtil.open(); } /** * if you use facebook logout,you must call this method and set params * @param activity * @param logoutButton * @param logOutStateListener */ public static void setFaceBookLogOutParams(View logoutButton,LogOutStateListener logOutStateListener){ //fbUtil.SetFaceBookLoginActivity(activity); fbUtil.SetFaceBookLogOutButton(logoutButton); fbUtil.SetOnFaceBookLogOutListener(logOutStateListener); fbUtil.open(); }; public static void onActivityResult(int requestCode, int resultCode, Intent data) { if(fbUtil!=null){ fbUtil.onActivityResult(requestCode, resultCode, data); }else if(tbutils!=null){ tbutils.onActivityResult(requestCode, resultCode, data); } } public static void OnDestory(){ if(fbUtil!=null){ fbUtil.OnDestory(); }else if(tbutils!=null){ tbutils.onDestroy(); } } }
这个是登陆成功的回调函数
public interface LogInStateListener {
public void OnLoginSuccess(User user,String logType);
public void OnLoginError(String error);
}
这个是退出的回调
public interface LogOutStateListener {
public void OnLogOutListener(boolean isSuccess,String logOutType);
}
完了在你的登陆的页面调用,可以参考下面的MainActivity
public class MainActivity extends FragmentActivity implements LogInStateListener{
Button facebookbutton;
Button tibbrButton;
Button tibbrforgotButton;
Button tibbrregButton;
FaceBookLoginUtil facebookutil;
TibbrLoginUtil tibbrUtil;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
facebookbutton=(Button)findViewById(R.id.facebook_button);
tibbrButton=(Button)findViewById(R.id.tibbr_button);
tibbrforgotButton=(Button)findViewById(R.id.tibbr_forget_button);
tibbrregButton=(Button)findViewById(R.id.tibbr_reg_button);
login();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
LoginManager.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
LoginManager.OnDestory();
}
@Override
public void OnLoginSuccess(User user,String logType) {
Intent intent=new Intent(MainActivity.this,Result.class);
intent.putExtra("user",(Serializable)user);
intent.putExtra("logtype", logType);
startActivity(intent);
}
@Override
public void OnLoginError(String error) {
System.out.println(error);
}
private void login(){
LoginManager.initialize(MainActivity.this);
LoginManager.setFaceBookLoginParams(MainActivity.this, facebookbutton, null,this);
);
}
然后在登陆成功跳转的页面参考下面
package com.tibco.integration.login; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.Button; import android.widget.TextView; import com.tibco.integeration.login.listener.LogOutStateListener; import com.tibco.integration.login.model.User; import com.tibco.integration.login.utils.Constant; import com.tibco.integration.login.utils.LoginManager; public class Result extends Activity implements LogOutStateListener{ String logType; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.resutl); User user=(User) getIntent().getSerializableExtra("user"); String logType=getIntent().getStringExtra("logtype"); TextView text=(TextView)findViewById(R.id.user); text.setText(user==null?"":user.getFirstname()+user.getLastname()+"\n logtype:"+logType); Button button=(Button)findViewById(R.id.logout_button); if(!logType.equals("") && logType.equals("facebook")){ LoginManager.initialize(Result.this); LoginManager.setFaceBookLogOutParams(button,this); }else if(!logType.equals("") && logType.equals("tibbr")){ LoginManager.initialize(Result.this); LoginManager.setTibbrLogOutParams( button, this); } } @Override protected void onSaveInstanceState(Bundle outState) { // TODO Auto-generated method stub super.onSaveInstanceState(outState); } @Override public void OnLogOutListener(boolean isSuccess,String logOutType) { Constant.showErrorDialog(Result.this, logOutType+" log out success!"); finish(); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); LoginManager.onActivityResult(requestCode, resultCode, data); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); } }
然后上配置文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tibco.integration.login" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name"> <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>//自己的appid <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".Result"></activity> <activity android:name="com.facebook.FacebookActivity" android:configChanges= "keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:label="@string/app_name" /> <!-- <provider android:authorities="com.facebook.app.FacebookContentProvider1234" android:name="com.facebook.FacebookContentProvider" android:exported="true" /> --> </application> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> </manifest>
运行图:
看不懂的或者有问题的留言一起讨论,谢谢