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 测试账号进行登录测试。

相关文章
|
4月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
468 4
|
5月前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
165 1
|
5月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
348 0
安卓项目:app注册/登录界面设计
|
6月前
|
IDE Android开发 iOS开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
【9月更文挑战第27天】在移动应用开发的世界中,Android和iOS是两个主要的操作系统平台。每个系统都有其独特的开发环境、工具和用户群体。本文将深入探讨这两个平台的关键差异点,并分析这些差异如何影响应用的性能、用户体验和最终的市场表现。通过对比分析,我们将揭示选择正确的开发平台对于确保项目成功的重要作用。
|
3月前
|
IDE 开发工具 Android开发
移动应用开发之旅:探索Android和iOS平台
在这篇文章中,我们将深入探讨移动应用开发的两个主要平台——Android和iOS。我们将了解它们的操作系统、开发环境和工具,并通过代码示例展示如何在这两个平台上创建一个简单的“Hello World”应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧,帮助你更好地理解和掌握移动应用开发。
107 17
|
4月前
|
Android开发 数据安全/隐私保护 虚拟化
安卓手机远程连接登录Windows服务器教程
安卓手机远程连接登录Windows服务器教程
650 4
|
4月前
|
Java API 开发工具
Cocos游戏如何快速接入安卓优量汇广告变现?
本文介绍了如何在Cocos游戏项目中快速接入安卓优量汇广告,通过详细的步骤指导,包括前期准备、编辑gradle和清单文件、核心代码集成等,帮助开发者轻松实现广告功能,增加游戏的盈利渠道。文中还提供了示例工程下载链接,方便开发者直接上手实践。
|
5月前
|
安全 Java 网络安全
Android远程连接和登录FTPS服务代码(commons.net库)
Android远程连接和登录FTPS服务代码(commons.net库)
65 1
|
5月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
163 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
6月前
|
开发工具 Android开发 iOS开发
安卓与iOS开发环境对比:选择适合你的平台
【9月更文挑战第26天】在移动应用开发的广阔天地中,安卓和iOS是两大巨头。它们各自拥有独特的优势和挑战,影响着开发者的选择和决策。本文将深入探讨这两个平台的开发环境,帮助你理解它们的核心差异,并指导你根据个人或项目需求做出明智的选择。无论你是初学者还是资深开发者,了解这些平台的异同都至关重要。让我们一起探索,找到最适合你的那片开发天地。

热门文章

最新文章

  • 1
    Android历史版本与APK文件结构
  • 2
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
  • 3
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 4
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 5
    【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
  • 6
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 7
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
  • 8
    escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
  • 9
    Android实战经验之Kotlin中快速实现MVI架构
  • 10
    即时通讯安全篇(一):正确地理解和使用Android端加密算法