Facebook登录
一、目录
一、开始配置
- Facebook Developers面板创建应用和基本配置
- 集成Facebook SDK 或者 使用依赖配置(二选一即可)
- 编辑资源和清单
- 开发秘钥散列的获取和配置
二、开始使用
- 标识应用事件(非必须)
- 添加登录按钮
- 注册登录回调 && 使用登录功能
三、额外功能
- 获取用户基本信息
- 获取用户好友信息
- 检查登录状态
- 退出注销登录
==================================================================================================
二、开始配置
一、Facebook Developers面板创建应用和基本配置
1. 地址:Facebook登录集成控制台
二、 集成Facebook SDK 或者 使用依赖配置(二选一即可,下面例子采取Gradle依赖)
1. project的build.gradle里加入jcenter仓库
buildscript {
repositories {
jcenter()
}
}
2. app的build.gradle里依赖配置
implementation 'com.facebook.android:facebook-login:[5,6)'
三、 编辑资源和清单
1.在strings.xml添加
<string name="facebook_app_id">配置APP_ID</string>
<string name="fb_login_protocol_scheme">fb + APP_ID</string>
2.在AndroidManifest.xml里添加
//1. 访问网络权限
<uses-permission android:name="android.permission.INTERNET"/>
//2. meta-data
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
//3. Activity
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
四、开发秘钥散列的获取和配置
1. 关联包名和Facebook登录的启动页: 在Facebook Developers快速开始的 >>> 5.为应用提供开发和发布密钥散列
2. 生成出来的散列秘钥配置: 在Facebook Developers快速开始的 >>> 6.为应用提供开发和发布密钥散列
// 官方提供了代码获取, 就是根据应用签名生成的(所以需要注意debug包生成的和release包生成的不一样,正式上线后重新用release包生成一个,当然如果签名一样就不影响了)
public static String getHashKey(Context context){
try {
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
for (android.content.pm.Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String KeyHash = Base64.encodeToString(md.digest(), Base64.DEFAULT);
Log.e("HashKey=========", KeyHash);// 打印出来的HashKey就是秘钥散列
return KeyHash;
}
} catch (Exception e) {
return "获取异常";
}
return null;
}
====================================================================================================
三、开始使用
一、标识应用事件(非必须)
1. 作用: 分析了解用户激活应用的频率、使用应用的时长,查看其他人口统计数据等功能使用
2. 使用: 在application里注册
// 可以不使用
FacebookSdk.sdkInitialize(getApplicationContext());
AppEventsLogger.activateApp(this);
二、添加登录按钮
关于区别了解请移步我另外一篇: Facebook登录自定义按钮
方式一: 使用Facebook自定义LoginButton
// 在xml里使用按钮
<com.facebook.login.widget.LoginButton
android:id="@+id/login_button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="60dp"/>
方式二: 使用自定义view点击按钮
// 自定义按钮无非就是多了一行调用登录api的代码
LoginManager.getInstance().logInWithReadPermissions(MainActivity.this, Arrays.asList("public_profile"));
三、注册登录回调 && 使用登录功能
1. 在登录页里注册登录的回调
callbackManager = CallbackManager.Factory.create();
LoginManager.getInstance().registerCallback(callbackManager,
new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
// TODO 成功后的操作
Toast.makeText(MainActivity.this, "登录成功", 0).show();
}
@Override
public void onCancel() {
// TODO 取消登录
Toast.makeText(MainActivity.this, "取消登录", 0).show();
}
@Override
public void onError(FacebookException exception) {
// TODO 登录失败
Toast.makeText(MainActivity.this, "登录失败", 0).show();
}
});
-
在登录页覆写的onActivityResult方法里回调登录的结果,这样manager里才能随时拿到最新的用户状态
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); callbackManager.onActivityResult(requestCode, resultCode, data); }
===================================================================================================
四、额外功能
一、获取用户基本信息
用户基本信息获取有两种方式: AccessTokenTracker 、 ProfileTracker 、GraphRequest.newMeRequest
如果只需要id和token用第一个;如果需要id、姓名、头像用第二个;如果需要完整的用户信息用第三个
- AccessTokenTracker 里能拿到的信息非常有限,通过token能拿到
fbID
和fbToken
- ProfileTracker 类存储了用户最基本的配置信息,被封装在
Profile
类里,
包括id
、firstName
、middleName
、lastName
、name
、linkUri
- GraphRequest类 是一个专用请求序列化数据的类,里面有两个非常重要的静态方法:
需要这些信息的前提是,在登录前向用户申请权限
- newPostRequest:可以拿到用户的基本信息,包括
姓名
、fbID
、性别
、头像
、生日
等- newMyFriendsRequest:可以拿到用户的好友列表
方式一:使用AccessTokenTracker
accessTokenTracker = new AccessTokenTracker() {
@Override
protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken) {
// Set the access token using
}
};
方式二:使用ProfileTracker
/**
* 获取用户facebook profile
*/
String fbName = null;
String fbId = null;
private void GetUserFacebookProfile(final AccessToken accessToken) {
Profile profile = Profile.getCurrentProfile();
if (profile == null) {
mProfileTracker = new ProfileTracker() {
@Override
protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) {
if (currentProfile != null) {
fbName = currentProfile.getName();
fbId = currentProfile.getId();
LoginResultTrans(new FacebookUserInfoBean(fbId, fbName, accessToken.getToken()));
/*Log.e(Constant.println.fragmentTag, "\n新建profile用户信息=====profile.toString());*/
}
mProfileTracker.stopTracking();
}
};
mProfileTracker.startTracking();
} else {
fbName = profile.getName();
fbId = profile.getId();
LoginResultTrans(new FacebookUserInfoBean(fbId, fbName, accessToken.getToken()));
/* Log.e(Constant.println.fragmentTag, "\n已存在profile用户信息===== profile.toString());*/
}
}
方式三: 使用GraphRequest.newMeRequest
// 用户信息批处理
GraphRequest meRequest = GraphRequest.newMeRequest(accessToken, new GraphRequest.GraphJSONObjectCallback() {
@Override
public void onCompleted(JSONObject object, GraphResponse response) {
if (response.getError() != null) {
String connection = response.getError().toString();
String errorMessage = response.getError().getErrorMessage();
Log.e(Constant.println.fragmentTag, "获取用户个人信息错误: " + connection + " 错误信息 =====" + errorMessage);
} else {
// code == 200
if (object != null) {
// 用户信息
Log.e(Constant.println.fragmentTag, "Response===" + response.toString());
}
}
}
});
二、获取用户好友信息
// 用户好友批处理
GraphRequest myFriendRequest = GraphRequest.newMyFriendsRequest(accessToken, new GraphRequest.GraphJSONArrayCallback() {
@Override
public void onCompleted(JSONArray jsonArray, GraphResponse response) {
// Application code for users friends
if (response.getError() != null) {
String connection = response.getError().toString();
String errorMessage = response.getError().getErrorMessage();
Log.e(Constant.println.fragmentTag, "获取用户好友信息错误: " + connection + " 错误信息 =====" + errorMessage);
}
// 用户好友信息
if (jsonArray != null) {
// TODO: 2019/7/25
Log.e(Constant.println.fragmentTag, "用户好友信息: " + jsonArray.toString());
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "public_profile,id,email,locale,location,user_gender,ser_birthday,user_friends");
myFriendRequest.setParameters(parameters);
GraphRequestBatch requestBatch = new GraphRequestBatch(myFriendRequest);// 可以同时执行多个请求
requestBatch.executeAsync();
三、检查登录状态
// 通过判断当前token是否有效,来确定是否已经登录
AccessToken accessToken = AccessToken.getCurrentAccessToken();
Booble isLoggedIn = accessToken != null && !accessToken .isExpired();
if (!isLoggedIn ) {
// 未登录
}else {
// 已自动登录
}
四、退出注销登录
LoginManager.getInstance().logOut();// 注销登录