Cocos Creator Android 平台 Facebook 原生登录(二)

简介: Cocos Creator Android 平台 Facebook 原生登录

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() {
            @Override
            public 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>() {
            @Override
            public 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());
            }
            @Override
            public 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);
            }
            @Override
            public 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)、设置回调



@Override
 protected 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] = func
            let 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 测试账号进行登录测试。

相关文章
|
7月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
730 4
|
15天前
|
Android开发 数据安全/隐私保护 开发者
Android自定义view之模仿登录界面文本输入框(华为云APP)
本文介绍了一款自定义输入框的实现,包含静态效果、hint值浮动动画及功能扩展。通过组合多个控件完成界面布局,使用TranslateAnimation与AlphaAnimation实现hint文字上下浮动效果,支持密码加密解密显示、去除键盘回车空格输入、光标定位等功能。代码基于Android平台,提供完整源码与attrs配置,方便复用与定制。希望对开发者有所帮助。
|
8月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
535 1
安卓项目:app注册/登录界面设计
|
3月前
|
存储 编解码 监控
Android平台GB28181执法记录仪技术方案与实现
本文介绍了大牛直播SDK的SmartGBD在执法记录仪场景中的应用。GB28181协议作为视频监控联网的国家标准,为设备互联互通提供规范。SmartGBD专为Android平台设计,支持音视频采集、编码与传输,具备自适应算法和多功能扩展优势。文章分析了执法记录仪的需求,如实时音视频传输、设备管理及数据安全,并详细阐述了基于SmartGBD的技术实现方案,包括环境准备、SDK集成、设备注册、音视频处理及功能扩展等步骤。最后展望了SmartGBD在未来智慧物联领域的广阔应用前景。
106 13
|
3月前
|
存储 编解码 开发工具
Android平台毫秒级低延迟HTTP-FLV直播播放器技术探究与实现
本文详细探讨了在Android平台上实现HTTP-FLV播放器的过程。首先介绍了FLV格式的基础,包括文件头和标签结构。接着分析了HTTP-FLV传输原理,通过分块传输实现流畅播放。然后重点讲解了播放器的实现步骤,涵盖网络请求、数据解析、音视频解码与渲染,以及播放控制功能的设计。文章还讨论了性能优化和网络异常处理的方法,并总结了HTTP-FLV播放器的技术价值,尤其是在特定场景下的应用意义。
150 11
|
3月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
8月前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
216 1
|
9月前
|
IDE Android开发 iOS开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
【9月更文挑战第27天】在移动应用开发的世界中,Android和iOS是两个主要的操作系统平台。每个系统都有其独特的开发环境、工具和用户群体。本文将深入探讨这两个平台的关键差异点,并分析这些差异如何影响应用的性能、用户体验和最终的市场表现。通过对比分析,我们将揭示选择正确的开发平台对于确保项目成功的重要作用。
|
6月前
|
IDE 开发工具 Android开发
移动应用开发之旅:探索Android和iOS平台
在这篇文章中,我们将深入探讨移动应用开发的两个主要平台——Android和iOS。我们将了解它们的操作系统、开发环境和工具,并通过代码示例展示如何在这两个平台上创建一个简单的“Hello World”应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧,帮助你更好地理解和掌握移动应用开发。
175 17
|
7月前
|
Android开发 数据安全/隐私保护 虚拟化
安卓手机远程连接登录Windows服务器教程
安卓手机远程连接登录Windows服务器教程
1242 4