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天前
|
Java Android开发 iOS开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
【7月更文挑战第8天】在移动应用开发的广阔天地中,Android与iOS两大平台各自占据着半壁江山。本文将深入探讨这两个平台在开发环境、用户界面设计、性能优化以及市场覆盖等方面的根本差异,并分析这些差异如何影响项目的成功。通过比较和分析,旨在为开发者在选择平台时提供更全面的视角,帮助他们根据项目需求和目标市场做出更明智的决策。
|
1天前
|
开发工具 Android开发 Swift
安卓与iOS开发环境对比:选择适合你的平台
【7月更文挑战第14天】在移动应用开发的广阔天地中,安卓和iOS两大平台各领风骚。本文将深入探讨这两个系统在开发环境上的差异,从编程语言、工具到生态系统的多维度比较,旨在为开发者提供一份实用的参考指南。无论你是初涉移动开发的新手,还是寻求跨平台解决方案的老手,这篇文章都将助你一臂之力,找到最适合你的开发路径。
|
1天前
|
IDE 开发工具 Android开发
安卓与iOS开发环境对比:选择合适的平台
【7月更文挑战第14天】本文深入探讨了安卓与iOS开发环境的差异,并分析了选择合适平台的考量因素。通过比较两者的开发工具、编程语言和用户群体,旨在帮助开发者做出明智的决策,以优化资源利用和提升应用性能。文章将提供实用的建议,助力开发者在竞争激烈的应用市场中脱颖而出。
8 2
|
4天前
|
IDE 开发工具 Android开发
安卓与iOS开发环境对比:选择适合你的平台
【7月更文挑战第11天】在移动应用开发的广阔天地中,安卓与iOS两大平台各据一方。它们不仅在用户群体上有所区别,更在开发环境、工具和生态系统上展现出独特的特色。本文将深入探讨这两个平台的开发环境差异,帮助开发者根据个人技能、项目需求及市场定位做出明智的选择。
16 3
|
7天前
|
移动开发 开发工具 Android开发
探索安卓与iOS开发的差异:平台特性与编程实践
【7月更文挑战第8天】在移动开发的广阔天地中,安卓和iOS这两大操作系统各自占据着半壁江山。它们在用户界面设计、系统架构及开发工具上展现出截然不同的特色。本文将深入探讨这两个平台在技术实现和开发生态上的关键差异,并分享一些实用的开发技巧,旨在为跨平台开发者提供有价值的见解和建议。
|
7天前
|
Android开发 Java 数据安全/隐私保护
「移动端」Android平台签名证书(.keystore)生成指南
发布Android APK需签名证书,步骤如下: 1. 安装JRE,如[JRE8](https://www.oracle.com/technetwork/java/javase/downloads/index.html),并添加到环境变量。 2. 使用`keytool -genkey`命令生成证书,例如: ``` keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore ``` 输入相关个人信息及密码。
32 0
「移动端」Android平台签名证书(.keystore)生成指南
|
6天前
|
搜索推荐 Android开发 iOS开发
探索Android与iOS开发的差异:平台特性与用户体验的对比分析
【7月更文挑战第9天】在移动应用开发的浩瀚海洋中,Android和iOS两大操作系统如同两座灯塔,指引着开发者们的航向。本文将深入探讨这两个平台在开发环境、用户界面设计、性能优化以及市场策略上的根本差异。我们将通过比较分析,揭示各自平台的独特优势和潜在挑战,为开发者提供决策支持,同时也为用户体验的提升指明方向。
|
4天前
|
开发工具 Android开发 iOS开发
探索Android与iOS开发的差异与挑战
【7月更文挑战第11天】在移动应用开发的广阔天地中,Android和iOS两大平台如同双子星座般耀眼,各自拥有独特的开发生态和用户群体。本文将深入分析这两个平台的显著差异,从技术架构到开发工具,再到市场定位,揭示它们之间的异同。通过比较,我们不仅能够更好地理解各自的优势和局限,还能洞察未来移动应用开发的趋势。
|
2天前
|
存储 移动开发 Android开发
使用kotlin Jetpack Compose框架开发安卓app, webview中h5如何访问手机存储上传文件
在Kotlin和Jetpack Compose中,集成WebView以支持HTML5页面访问手机存储及上传音频文件涉及关键步骤:1) 添加`READ_EXTERNAL_STORAGE`和`WRITE_EXTERNAL_STORAGE`权限,考虑Android 11的分区存储;2) 配置WebView允许JavaScript和文件访问,启用`javaScriptEnabled`、`allowFileAccess`等设置;3) HTML5页面使用`<input type="file">`让用户选择文件,利用File API;
|
5天前
|
开发者 Kotlin Android开发
Kotlin协程在Android开发中的应用
【7月更文挑战第10天】Kotlin协程简化了Android异步编程,提供轻量级并发。挂起函数让异步代码看起来同步,不阻塞线程,便于管理。在项目中,添加Kotlin和协程依赖,如`kotlinx.coroutines-core`和`kotlinx-coroutines-android`。使用`CoroutineScope`和`launch`处理耗时任务,如网络请求,避免主线程阻塞。挂起函数和调度器控制执行上下文,适应不同任务需求。