Android集成Facebook第三方登录
一、前言:
首次接触海外项目,开发环节与测试流程刚开始搞得一头雾水,历时两周终于把登录和支付调通了,特此记录下;
不过总结下来,与国内流程不同的点,主要是测试流程,需要专门的测试账号与测试权限才能测通
首先打开开发文档,地址如下,跟着开发文档一步步走就好,细节上官方文档没有提到的或容易忽视的,我在后续步骤均已书写,跟着走没问题的
Faccebook登录开发文档地址
注意:获取用户信息必看
- 地址1:https://www.codenong.com/41235407/
- 地址2:https://blog.csdn.net/yanbing1995/article/details/80008514
二、接入
1、 新建应用很简单,自行按分类新建。建一个就可以,ios和android
在里面各自配置就好
2、集成sdk使用maven
- 导入当前最新版,如果不止集成登录功能用这个全的
//facebook
implementation 'com.facebook.android:facebook-android-sdk:12.3.0'
- AndroidManifest.xml 中添加
<!-- facebook facebook_client_token:是应用-设置-高级-客户端口令 -->
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
<meta-data
android:name="com.facebook.sdk.ClientToken"
android:value="@string/facebook_client_token" />
<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>
3、生成秘钥散列前提准备:
安装:openssl-for-windows OpenSSL 库
准备好keystore或jks文件,要用到该文件的地址;以下 xxx == jks或keystore名
1、生成开发密钥散列
keytool -exportcert -alias androiddebugkey -keystore D:/heiyanabroad-app/app/xxx.keystore| openssl sha1 -binary | openssl base64
2、生成发布密钥散列
keytool -exportcert -alias xxx -keystore D:/heiyanabroad-app/app/xxx.jks | openssl sha1 -binary | openssl base64
3、也可以自己通过签名,生成sha1值,再用base64压缩
图片.png
将SHA1值复制到剪贴板,如
CD:A1:EA:A3:5C:5C:68:FB:FA:0A:6B:E5:5A:72:64:DD:26:8D:44:84所示,然后打开http://tomeko.net/online_tools/hex_to_base64.php将SHA1值转换为base64。这是Facebook所要求的,获取生成的哈希值********************=,并将密钥哈希值复制到Facebook应用程序。
在通过下面这个网站压缩:
SHA1转化为BASE64.php
生成页面.png
4、注意:
1、我debug运行的时候需要填的是发布秘钥散列;
2、还有我是首次上传到google play,让Google 管理应用签名密钥,上传到google发布后,需要生成一个新的秘钥,在google:应用-设置-应用完整性,下载上传秘钥证书
图片.png
keytool -import -file D:/heiyanabroad-app/app/upload_cert.der -keystore D:/heiyanabroad-app/app/adcadc.keystore
5、生成的秘钥都填到facebook这里来:
图片.png
4、登录按钮,官方文档给出的是封装好的,不好用,可以用自定义的
1、添加权限
public void login(Activity context,boolean IsLogin) {
ShareUitls.putBoolean(context,"FaceBookIsLogin",IsLogin);
//添加public_profile和email权限
LoginManager.getInstance().logInWithReadPermissions(context, Arrays.asList("public_profile","email"));
}
2、注册facebook回调
/**
* facebook登录
*/
//private static final String EMAIL = "email";
private void faceBookLogin() {
faceBookSdkManager = FaceBookSdkManager.getInstance(activity);
faceBookSdkManager.registerCallback(new FaceBookSdkManager.FacebookLoginCallBack() {
@Override
public void onSuccess(String accessToken) {
MyToash.Log("login", "faceBook----accessToken="+accessToken);
abroadLogin(activity, 1, accessToken);
}
@Override
public void onCancel() {
}
@Override
public void onError(String message) {
MyToash.Log("login", "faceBook----FaceBookError="+message);
}
});
}
/**
* facebook注册回调
* @param callBack
*/
public void registerCallback(final FacebookLoginCallBack callBack) {
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
MyToash.Log("login","faceBook----accessToken:"+loginResult.getAccessToken().getToken());
AccessToken accessToken = loginResult.getAccessToken();
if (accessToken != null) {
if (callBack != null) {
callBack.onSuccess(accessToken.getToken());
}
}
//再次请求获取用户信息
GraphRequest mGraphRequest = GraphRequest.newMeRequest(loginResult.getAccessToken(),new GraphRequest.GraphJSONObjectCallback(){
@Override
public void onCompleted(@Nullable JSONObject jsonObject, @Nullable GraphResponse response) {
if (response.getError() != null) {
// handle error
} else {
//获取邮箱
String email = jsonObject.optString("email");
String name = jsonObject.optString("name");
String birthday = jsonObject.optString("user_birthday");
//MmkvUtils.encode(CommonConstantUtils.FACEBOOK_EMAIL,email);
MyToash.Log("login","faceBook----email:"+email);
MyToash.Log("login","faceBook----name:"+name);
MyToash.Log("login","faceBook----birthday:"+birthday);
}
}
});
//组装参数
Bundle parameters = new Bundle();
parameters.putString("fields","id,name,email,gender, birthday");
mGraphRequest.setParameters(parameters);
//发起请求
mGraphRequest.executeAsync();
}
@Override
public void onCancel() {
if (callBack != null) {
callBack.onCancel();
}
}
@Override
public void onError(FacebookException error) {
if (error instanceof FacebookAuthorizationException){
if (AccessToken.getCurrentAccessToken() != null){
LoginManager.getInstance().logOut();
}
}
String message = error.getMessage();
try {
JSONObject jsonObject = new JSONObject(message);
String errorMessage = jsonObject.optString("errorMessage");
int errorCode = jsonObject.optInt("errorCode");
MyToash.Log("accessTokenerrorCode",errorCode);
if (callBack != null) {
callBack.onError(errorMessage + "(" + errorCode + ")");
}
} catch (JSONException e) {
e.printStackTrace();
if (callBack != null) {
callBack.onError("");
}
}
}
});
}
3、退出登录
public void logout() {
LoginManager.getInstance().logOut();
}
4、检查登录状态:
AccessToken accessToken = AccessToken.getCurrentAccessToken();
boolean isLoggedIn = accessToken != null && !accessToken.isExpired();
5、测试
应用未在google play上架前,测试的时候需要登录开发者facebook账号,用来测试;或者如下方式添加测试者账号;
图片.png
-
测试账号与开发者账号加好友
-
选择用户身份,测试账号
图片.png
-
然后测试者会出现待回复,此时在电脑端登录测试者的账号,消息里找到邀请信息,接受,就可以用这个测试账号登录app了
图片.png
6、facebook管理类示例
package com.youjiakeji.yjkjreader.ui.utils;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.Nullable;
import com.facebook.AuthenticationToken;
import com.facebook.AuthenticationTokenClaims;
import com.facebook.FacebookAuthorizationException;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.youjiakeji.yjkjreader.constant.CommonConstantUtils;
import com.youjiakeji.yjkjreader.utils.ShareUitls;
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Arrays;
/**
* Created by zyf on 2017/3/24.
*/
public class FaceBookSdkManager {
private static FaceBookSdkManager mInstance;
private CallbackManager callbackManager;
public static FaceBookSdkManager getInstance(Context context) {
if (mInstance == null) {
mInstance = new FaceBookSdkManager(context.getApplicationContext());
}
return mInstance;
}
public FaceBookSdkManager(Context context) {
FacebookSdk.sdkInitialize(context);
callbackManager = CallbackManager.Factory.create();
}
public CallbackManager getCallbackManager() {
return callbackManager;
}
/**
* facebook注册回调
*
* @param callBack
*/
public void registerCallback(final FacebookLoginCallBack callBack) {
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
MyToash.Log("login", "faceBook----accessToken:" + loginResult.getAccessToken().getToken());
AccessToken accessToken = loginResult.getAccessToken();
if (accessToken != null) {
if (callBack != null) {
callBack.onSuccess(accessToken.getToken());
}
}
//再次请求获取用户信息
GraphRequest mGraphRequest = GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
@Override
public void onCompleted(@Nullable JSONObject jsonObject, @Nullable GraphResponse response) {
if (response.getError() != null) {
// handle error
} else {
//获取邮箱
String email = jsonObject.optString("email");
String name = jsonObject.optString("name");
String birthday = jsonObject.optString("user_birthday");
//MmkvUtils.encode(CommonConstantUtils.FACEBOOK_EMAIL,email);
MyToash.Log("login", "faceBook----email:" + email);
MyToash.Log("login", "faceBook----name:" + name);
MyToash.Log("login", "faceBook----birthday:" + birthday);
}
}
});
//组装参数
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,gender, birthday");
mGraphRequest.setParameters(parameters);
//发起请求
mGraphRequest.executeAsync();
}
@Override
public void onCancel() {
if (callBack != null) {
callBack.onCancel();
}
}
@Override
public void onError(FacebookException error) {
if (error instanceof FacebookAuthorizationException) {
if (AccessToken.getCurrentAccessToken() != null) {
LoginManager.getInstance().logOut();
}
}
String message = error.getMessage();
try {
JSONObject jsonObject = new JSONObject(message);
String errorMessage = jsonObject.optString("errorMessage");
int errorCode = jsonObject.optInt("errorCode");
MyToash.Log("accessTokenerrorCode", errorCode);
if (callBack != null) {
callBack.onError(errorMessage + "(" + errorCode + ")");
}
} catch (JSONException e) {
e.printStackTrace();
if (callBack != null) {
callBack.onError("");
}
}
}
});
}
public void login(Activity context, boolean IsLogin) {
ShareUitls.putBoolean(context, "FaceBookIsLogin", IsLogin);
//添加public_profile和email权限
LoginManager.getInstance().logInWithReadPermissions(context, Arrays.asList("public_profile", "email"));
}
/**
* 注销
* 如果注销的时候,不调用这个方法,当换一个新的账号登录的时候,会出现 UserData logged in as different Facebook user 异常
*/
public void logout() {
LoginManager.getInstance().logOut();
}
public interface FacebookLoginCallBack {
void onSuccess(String accessToken);
void onCancel();
void onError(String message);
}
}
参考:https://blog.csdn.net/liyuali2012/article/details/121429613