Cocos Creator Android 平台 Facebook 原生登录
在做海外项目中,经常需要接入Facebook SDK ,现将CocosCreator Android 平台 Facebook 登录的接入流程记录下来,以备有需要的朋友做参考。
一、准备工作
1、首先在facebook 开发者平台 注册账号,创建app,获取app的应用编号。
怎么注册账号,怎么创建app ,这里就不再细说。
app的应用编号和密钥,如下所示:
2、设置应用密钥散列
生成密钥散列有2种方式:
(1)、通过代码获取
//获取facebook所需的密钥散列
try {PackageInfo info = getPackageManager().getPackageInfo("com.x.x", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {MessageDigest md = MessageDigest.getInstance("SHA");md.update(signature.toByteArray());showLog("Base64 hash------" + Base64.encodeToString(md.digest(), Base64.DEFAULT));}
} catch (PackageManager.NameNotFoundException e) {} catch (NoSuchAlgorithmException e) {}
(2)、通过工具进行获取
第一步,通过命令行的方式获取到证书指纹SHA1
发布证书指纹获取方式:
keytool -exportcert -alias YOUR_RELEASE_KEY_ALIAS -keystore YOUR_RELEASE_KEY_PATH | openssl sha1 -binary | openssl base64
开发证书指纹获取方式:
keytool -exportcert -alias androiddebugkey -keystore "C:\Users\USERNAME\.android\debug.keystore" | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" sha1 -binary | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" base64
证书指纹示例:
SHA1: 9D:2F:E0:3C:8E:DF:ED:8C:2B:28:88:92:60:A3:82:63:81:4F:3D:9D
第二步,使用工具,将SHA1 证书指纹转化为密钥散列
在线工具:http://tomeko.net/online_tools/hex_to_base64.php
详细使用步骤,请查看根据 sha-1 证书值获取 Facebook 的登录需要使用的散列值
密钥散列可填写多个:
3、添加平台
这里以添加 google play 平台为例进行说明。
(1)、点击下方“添加平台” 按钮 ,在弹出的二级页面依次选择 android ->google play 。
(2)、设置软件包名,包名就是项目包名 com.xxx.xxx。
(3)、设置类名,类名里面填写启动activity 全路径,例如:org.cocos2dx.javascript.AppActivity。
3、创建测试账号,修改密码
二、代码部分调整
1、在项目层 build.gradle ,引入facebook 最新版本sdk。
implementation 'com.facebook.android:facebook-login:latest.release'
implementation 'com.facebook.android:facebook-android-sdk:latest.release'
2、AndroidManifest.xml 配置
(1)、添加网络访问权限,如果已经开启,则忽略。
<uses-permission android:name="android.permission.INTERNET"/>
(2)、在 application 添加 meta-data 元素 和针对 Facebook 的 activity 元素。
<!-- SDK Facebook start! --><meta-data android:name="com.facebook.sdk.ApplicationId"android:value="@string/facebook_app_id"/><activity android:name="com.facebook.FacebookActivity"android:configChanges= "keyboard|keyboardHidden|screenLayout|screenSize|orientation"android:label="@string/app_name" />
<!-- SDK Facebook end! -->
(3)、在 application 启动activity 元素添加 scheme
<activityandroid:name="org.cocos2dx.javascript.AppActivity"android:screenOrientation="sensorPortrait"android:configChanges="orientation|keyboardHidden|screenSize|screenLayout"android:label="@string/app_name"android:theme="@android:style/Theme.NoTitleBar.Fullscreen"android:launchMode="singleTask"android:exported="true"android:taskAffinity="" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><intent-filter android:autoVerify="true"><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、res/values/strings.xml 配置
<string name="facebook_app_id">285717330186354</string><string name="fb_login_protocol_scheme">fb285717330186356</string>
facebook_app_id :app的应用编号
fb_login_protocol_scheme:fb+app的应用编号
4、登录调用、回调通知、用户信息获取简单封装
关于Facebook 登录,官方提供了 LoginButton 和LoginManager 两种方式。
不过我们经常使用自己的View 来显示 ,因此这里采用 LoginManager 的方式实现。
详细请查看以下代码:
package org.cocos2dx.javascript.tools;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookRequestError;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.HttpMethod;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;import org.cocos2dx.javascript.Native;
import org.json.JSONException;
import org.json.JSONObject;import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;public class FaceBookUtils {private CallbackManager m_callbackManager =null;private String m_actTag ="FaceBookUtils";private String m_facebookLoginCallBack="";private Activity m_activity=null;private static FaceBookUtils g_Instace = null;public static FaceBookUtils getInstance() {if (null == g_Instace) {g_Instace = new FaceBookUtils();}return g_Instace;}public void loginFacebook(final String callback){m_facebookLoginCallBack = callback;LoginManager.getInstance().logInWithReadPermissions(m_activity, Arrays.asList("public_profile"));}public void onActivityResult(int requestCode, int resultCode, Intent data) {m_callbackManager.onActivityResult(requestCode,resultCode,data);}public void getUserFacebookBasicInfo(Map<String,String> inmap) {final String id = inmap.get("id");final String token = inmap.get("token");final String app = inmap.get("app");// 获取基本文本信息Log.d(m_actTag, "准备获取facebook用户基本信息");GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() {@Overridepublic void onCompleted(JSONObject object, GraphResponse response) {if (response == null) {Log.d(m_actTag, "无法获取fb用户基本信息");return;}Log.d(m_actTag, "获取fb用户基本信息完毕,object是" + object);JSONObject responseJsonObject = response.getJSONObject();Log.d(m_actTag, "而response 的object是" + responseJsonObject);//这两个jsonObject是一样的if (responseJsonObject == null) {Log.d(m_actTag, "无法获取fb用户基本信息" + response.getError().getErrorType() + " " + response.getError().getErrorMessage());return;}Map<String,String> map = new HashMap<String, String>();map.put("result", "11");map.put("info", "fb info success");map.put("id", id);map.put("token", token);map.put("appid", app);map.put("firstName", getFacebookGraphResponseString(responseJsonObject, "first_name"));map.put("lastName", getFacebookGraphResponseString(responseJsonObject, "last_name"));map.put("userName", getFacebookGraphResponseString(responseJsonObject, "name"));
// map.put("birthday", getFacebookGraphResponseString(responseJsonObject, "birthday"));//map.put("updateTime", getFacebookGraphResponseString(responseJsonObject, "updated_time"));
// map.put("email", getFacebookGraphResponseString(responseJsonObject, "email"));
// map.put("gender", getFacebookGraphResponseString(responseJsonObject, "gender"));//获取用户头像 (小)//JSONObject object_pic = object.optJSONObject( "picture" ) ;//JSONObject object_data = object_pic.optJSONObject( "data" ) ;//String photo = object_data.optString( "url" ) ;//map.put("head", photo);Native.nativeToLogic(m_facebookLoginCallBack,map);}});Bundle parameters = new Bundle();
// parameters.putString("fields", "id,name,link,email,first_name,last_name,gender,picture,locale,timezone,updated_time,verified");parameters.putString("fields", "id,name,first_name,last_name");request.setParameters(parameters);request.executeAsync();}public String getFacebookGraphResponseString(JSONObject graphResponse, String flag) {String value = "";try {value = graphResponse.getString(flag);} catch (JSONException e) {e.printStackTrace();}Log.d(m_actTag, "getFacebookInfo flag="+flag+" result="+value);return value;}public void getFacebookUserPictureAsync(String facebookUserId) {Log.d(m_actTag, "getFacebookUserPictureAsync");Bundle parameters = new Bundle();parameters.putBoolean("redirect", false);parameters.putString("height", "200");parameters.putString("type", "normal");parameters.putString("width", "200");GraphRequest graphRequest= new GraphRequest(AccessToken.getCurrentAccessToken(), "/" + facebookUserId + "/picture", parameters, HttpMethod.GET, new GraphRequest.Callback() {public void onCompleted(GraphResponse response) {if (response == null) {Log.d(m_actTag, "get facebook photo fail");return;}if (response.getError() != null) {FacebookRequestError facebookRequestError = response.getError();Log.d(m_actTag, "get facebook photo fail 2::" + facebookRequestError.getErrorMessage());return;}JSONObject responseJsonObject = response.getJSONObject();if (responseJsonObject == null) {Log.d(m_actTag, "get facebook photo fail 3");return;}Log.d(m_actTag, "facebook photo info:" + responseJsonObject.toString());String avatarUrl = "";try {JSONObject dataJsonObject = responseJsonObject.getJSONObject("data");avatarUrl = dataJsonObject.getString("url");//分割出参数部分
// String[] sourceStrArray = avatarUrl.split("\\?");avatarUrl = URLEncoder.encode(avatarUrl, "UTF-8");Log.d(m_actTag, "facebook photo avatarUrl:" + avatarUrl);Map<String,String> map = new HashMap<String, String>();map.put("result", "12");map.put("info", "fb head success");map.put("head", avatarUrl);map.put("height", dataJsonObject.getString("height"));map.put("width", dataJsonObject.getString("width"));map.put("isSilhouette", dataJsonObject.getString("is_silhouette"));Native.nativeToLogic(m_facebookLoginCallBack,map);} catch (Exception e) {Log.d(m_actTag, "get facebook photo fail 4"+e.getStackTrace().toString());}}});Log.d(m_actTag, "getFacebookUserPictureAsync version:"+graphRequest.getVersion()+"");graphRequest.executeAsync();}public void initSDK( final Activity activity){m_activity = activity;m_callbackManager = CallbackManager.Factory.create();Log.d("fb login","initSDK");LoginManager.getInstance().registerCallback(m_callbackManager, new FacebookCallback<LoginResult>() {@Overridepublic void onSuccess(LoginResult loginResult) {Log.e(m_actTag, "facebook login success: " + loginResult.getAccessToken().getToken());Map<String,String> map = new HashMap<String, String>();map.put("result", "1");map.put("info", "fb login success");map.put("id", loginResult.getAccessToken().getUserId());map.put("token", loginResult.getAccessToken().getToken());map.put("app", loginResult.getAccessToken().getApplicationId());Native.nativeToLogic(m_facebookLoginCallBack,map);Log.d("fb login","success!!!!!");//紧接着获取用户信息getUserFacebookBasicInfo(map);
// getFacebookUserPictureAsync(loginResult.getAccessToken().getUserId());}@Overridepublic void onCancel() {Log.e(m_actTag, "facebook login cancel");Map<String,String> map = new HashMap<String, String>();map.put("result", "2");map.put("info", "user cancel");Log.d("user","cancel!!!!!");Native.nativeToLogic(m_facebookLoginCallBack,map);}@Overridepublic void onError(FacebookException error) {Log.e(m_actTag, "facebook login error:" + error.toString());Map<String,String> map = new HashMap<String, String>();map.put("result", "3");map.put("info", error.toString());Log.d("facebook login","error!!!!!");Native.nativeToLogic(m_facebookLoginCallBack,map);}});}
}
5、AppActivity 中使用 FaceBookUtils 封装类
(1)、onCreate 时初始化
FaceBookUtils.getInstance().initSDK(this);
(2)、设置回调
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {FaceBookUtils.getInstance().onActivityResult(requestCode, resultCode, data);super.onActivityResult(requestCode, resultCode, data);
}
(3)、登录接口导出
public static void loginFacebook(final String callback) {FaceBookUtils.getInstance().loginFacebook(callback);}
6、js 层 对java 的 Native 封装
private static CallBackKey: string = "nativeCallback";private static _callBackPrefix: string; //回调集合字符前缀private static _prevErr = ""private static _hasInited = false;public static init() {if (cc.sys.isBrowser) {return}if (this._hasInited) {return}this._hasInited = true;window[this.CallBackKey] = {}; //回调函数集合this._callBackPrefix = "window." + this.CallBackKey + ".";//捕获异常if (cc.sys.isNative) {window.__errorHandler = function (file: any, line: any, error: any, stack: any) {if (this._prevErr != error + line) {stack = String(stack)console.log("========== GOT JS/TS ERROR ==========")console.log("file:" + file, "line:" + line, "error:" + error)console.log(stack)this._prevErr = error + line;}}}}// 登陆fb Native.loginFacebook((ret:any)=>{cc.log(ret)},"(%s)")public static loginFacebook(func: any,funcParams:string): void {if (cc.sys.isNative) {let cbKey: string = "loginFacebook"window[this.CallBackKey][cbKey] = funclet ret = 0;if (cc.sys.os == cc.sys.OS_ANDROID) {ret = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "loginFacebook", "(Ljava/lang/String;)V", this._callBackPrefix + cbKey + funcParams);}}}
7、js 层调用Native. loginFacebook
getPlayerInfoBySdk(){let self = this;Native.loginFacebook((ret: any) => {self.facebookSdkBack(ret)},"(%s)")}//请求SDK返回facebookSdkBack(backInfo:any){if(backInfo){if(backInfo.result == "2"){//用户取消FB登录UIHelper.UICenterNotice(backInfo.info)}else if(backInfo.result == "3"){//FB登录失败UIHelper.UICenterNotice(backInfo.info)}else if(backInfo.result == "11"){//FB登录成功并返回用户数据this.checkFbToken(backInfo);}else if(backInfo.result == "12"){//FB登录成功并返回头像信息}}}
三、测试登录
需要注意2点:
(1)、使用的打包证书需要与facebook 开发者平台生成密钥散列证书一致。
(2)、需要使用 facebook 测试账号进行登录测试。
Cocos Creator Android 平台 Facebook 原生登录相关推荐
- Cocos Creator Android 平台 Google 原生登录
在海外项目中,我们通常需要接入 Google 帐号登录,这样可以提高应用使用率. 下面以 Android 平台 接入 Google 原生登录为例,进行详细说明. 一.准备工作 1.需要 Android ...
- Android Facebook原生登录
前言: 在写这篇文章之前先吐槽一下自己的英文水平,之前一直没感觉,因为做的项目都是国内的项目,很少看英文文档.但是,自从换了一个工作之后,做的是国外的项目.并且,写了给第三方写了一个SDK,需要使用G ...
- cocos creator利用ShareSDK实现微信登录功能
首先在ShareSDK官网下载SDK或者在android studio中配置build.gradle. ShareSDK Maven集成文档 注:使用ShareSDK maven集成方式,不需要在An ...
- cocos creator ios 接入 facebook sdk login
主程序是cocos creator 发布ios时要接facebook登录的sdk cocos creator 发布ios版本后 按官方文档配置接入,碰到以下问题 执行 sudo gem install ...
- cocos creator android 真机调试配置密匙
android 真机调试与打包 真机调式 cocos creator 环境配置完成后 选择 编辑器 => 项目 => 构建发布 => android => 构建 构建完成后打开 ...
- Android——第三方Facebook授权登录获取用户信息
由于项目中需要使用Facebook进行一键登录,所以记录下步骤,其实小伙伴直接看官网也可以,介绍的蛮详细的,先看下效果图吧. 遵循以下步骤将Facebook登录添加到您的应用. Facebook开发者 ...
- 用 Cocos Creator 制作平台跳跃游戏
前言 平台跳跃类游戏如<超级马里奥><Celeste蔚蓝>等,非常考验玩家的操作和判断,有着非常本真的游戏乐趣.这类游戏乍一看,挺容易做的,但是要做好却不太容易.今天,我将使用 ...
- cocos creator android之微信开放平台修改签名 baseResp.errCode=-6
1.baseResp.errCode=-6 就代表签名和打包的秘钥生成的签名不一致,会导致调起来的微信授权登录页一片空白,我用cocos的应用包名去生成md5签名和用keystore生成的签名不一致, ...
- Android集成Facebook第三方登录,全流程
首次接触海外项目,开发环节与测试流程刚开始搞得一头雾水,历时两周终于把登录和支付调通了,特此记录下: 不过总结下来,与国内流程不同的点,主要是测试流程,需要专门的测试账号与测试权限才能测通 首先打开开 ...
最新文章
- 【网络流24题】飞行员配对方案问题
- javascript DOM基础(一)
- [Idea Fragments]2013.08.08
- top.location.href和localtion.href有什么不同
- oracle密码不能重复用_重复码
- iOS开发之#iPhone6与iPhone6Plus适配#Xcode6.0/Xcode6.1上传应用过程中一些变动以及#解决方案#
- vue ---- 组件综合案例(购物车案例)
- 互联网十几年 我们错失了哪些创业机会
- 使用soap遇到的缓存问题
- 传统词向量nlp处理的优缺点_吴恩达深度学习笔记(126) | NLP | GloVe 词向量
- 学习成果区块链问世,中科宇创为人才能力认证提供权威账本
- 在火狐浏览器里怎么看请求头
- 在Vue项目中使用阿里巴巴矢量图
- android布局跑马灯,Android之跑马灯详解
- 计算机网络怎样连手机软件,手机怎么共享网络给电脑_手机如何共享电脑网络-win7之家...
- [设备驱动] 最简单的内核设备驱动--字符驱动
- 面向对象封装案例 --- 士兵突击
- 佐治亚大学计算机工程本科课程,美国大学本科专业排名:计算机工程.docx
- Match Points CodeForces 1156C 二分答案
- 淘淘商城第44讲——搭建搜索系统工程
热门文章
- 多数据源/动态数据源的解决方案
- ‘gbk‘ codec can‘t decode byte 0xa4 in position 4: illegal multibyte sequence
- 图像处理实验,中值滤波处理椒盐噪声
- xfire ---java web服务器引擎
- matlab离散数据微积分
- OpenCV 识别图片中的米粒个数,并计算米粒的平均面积和长度(转)
- 使用Visual Studio+OpenCV进行的Susan算子边缘检测及数米粒图像处理实验
- xp锁定计算机快捷方式,XP系统怎么锁定界面快捷方式到任务栏
- 身在互联网,该如何提高自身的核心竞争力?
- 智能巡更系统|工业园区无线通信系统