美文网首页
使用eclipse实现cocos2d-x微信登录

使用eclipse实现cocos2d-x微信登录

作者: strayer_ | 来源:发表于2017-10-31 13:15 被阅读0次
    • 使用eclipse导入proj.android。
    • 创建包名.wxapi
    • 导入微信sdk


      image.png
    image.png
    • 创建JinHelper.java
    image.png
    • AppActivity.java
    public static final String TAG = "NiuBuTing_Weixin_SDK";
        public static final String APP_ID = "你的APP_iD";
        public static IWXAPI api;
        private static AppActivity instance = null;
     
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            instance = this;
            // 注册到微信
            regToWx();
        }
     
        //注册到微信
        private void regToWx() {
            //工厂模式创建微信api
            api = WXAPIFactory.createWXAPI(this, APP_ID, false);
     
            //注册程序
            api.registerApp(APP_ID);
        }
     
        //启动微信
        private static boolean LaunchWX() {
            boolean ret = false;
            if (!api.isWXAppInstalled())
            {//判断是否安装微信
                Toast.makeText(instance, "没有安装微信,请先安装微信!", Toast.LENGTH_LONG).show();
                return ret;
            }
            if (api.openWXApp())
            {//判断打开微信是否成功
                Log.d(TAG, "微信打开成功!");
                ret = true;
            }
            else
            {
                Log.d(TAG, "微信打开失败!");
                ret = false;
            }
     
            return ret;
        }
     
        //将图片解析成一个二进制数组
        private byte[] bmpToByteArrar(final Bitmap bitmap, final boolean isRecycle){
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
            if (isRecycle)
            {
                bitmap.recycle();
            }
     
            byte[] result = outputStream.toByteArray();
     
            try
            {
                outputStream.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return result;
        }
     
        //微信登录
        public static void WXLogin(){
            Log.d(TAG, "login-------------");
            WXEntryActivity.ReqState = 0;
            final SendAuth.Req req = new SendAuth.Req();
            req.scope = "snsapi_userinfo";  //这里不能改
            req.state = "QTNiuBuTing";  //这里改成你自己的数据
            api.sendReq(req);
        }
     
        //分享到聊天窗口
        public static void WXShareMsgToFriends(final String userNickName,
                                               final String roomNum,
                                               final String inningsNum,
                                               final String peopleNum,
                                               final int playType){
            //这里的参数是看你自己你需要的话就行,但是在cocos里面调用这个方法的你也传递数值过来
     
            String strPlayType = "轮庄牛牛";
     
            if (playType == 1)   //2为轮庄
            {
                strPlayType = "抢庄牛牛";
            }
     
            WXEntryActivity.ReqState = 1;
     
            //封装一个链接,点击跳转到指定网址
            WXWebpageObject webpag = new WXWebpageObject();
            webpag.webpageUrl = "https://www.xxxxxxxxxxxxx.com/";
     
            //封装游戏图标
            Bitmap bitmap = BitmapFactory.decodeResource(instance.getResources(), R.drawable.icon);
            Bitmap thumb = Bitmap.createScaledBitmap(bitmap, 108, 108, true);
            bitmap.recycle();
     
            //封装分享内容
            WXMediaMessage msg = new WXMediaMessage(webpag);
            msg.thumbData = instance.bmpToByteArrar(thumb, true);
            msg.title = "我是 " + userNickName;  //这个是标题
            msg.description = "[" + strPlayType + "]"  //这个是描述
                    + " 房间号:" + roomNum + "。"
                    + " 局数:" + inningsNum + "。"
                    + " 人数:" + peopleNum + "人。"
                    + "一起来玩一玩吧!";
     
            //封装请求
            SendMessageToWX.Req req = new SendMessageToWX.Req();
            req.transaction = buildTransaction("webpag");
            req.message = msg;
            req.scene = SendMessageToWX.Req.WXSceneSession;
     
            //发送请求
            api.sendReq(req);
        }
     
        //生成一个微信唯一请求标识符
        private static String buildTransaction(final String type) {
            return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
        }
    
    
    • WXEntryActivity.java

    放到包名.wxapi文件夹下
    WXEntryActivity.java 和 .wxapi 不要改名
    包名对应的是微信记录的那个包名

    public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
        private final String TAG = "NiuBuTing_Weixin_SDK";
        public static int ReqState = -1;  //0为登录, 1为分享
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
     
            AppActivity.api.handleIntent(this.getIntent(), this);
            //如果没回调onResp,八成是这句没有写
        }
     
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
     
            setIntent(intent);
            AppActivity.api.handleIntent(intent, this);
        }
     
        // 微信发送请求到第三方应用时,会回调到该方法
        @Override
        public void onReq(BaseReq req) {
            finish();
        }
     
        @Override
        public void onResp(BaseResp resp) {
            Log.d(TAG, "onResp:");
            switch (resp.errCode) {
                case BaseResp.ErrCode.ERR_OK:
                    Log.d(TAG, "请求成功");
                    if (ReqState == 0)  //这个是自己加用于判断是登录还是分享,你们可以去掉判断只要里面的代码就行了
                    {
                        SendAuth.Resp sendResp = (SendAuth.Resp) resp;
                        JniHelper.onResp(sendResp.code); //这个登录了之后用于回调cocos端函数的映射代码
                        Log.d(TAG, sendResp.code);
                    }
                    break;
                case BaseResp.ErrCode.ERR_USER_CANCEL:
                    //发送取消
                    Toast.makeText(this, "请求取消", Toast.LENGTH_LONG).show();
                    break;
                case BaseResp.ErrCode.ERR_AUTH_DENIED:
                    //发送被拒绝
                    Toast.makeText(this, "请求被拒绝", Toast.LENGTH_LONG).show();
                    break;
                default:
                    //发送返回
                    Toast.makeText(this, "请求返回", Toast.LENGTH_LONG).show();
                    break;
            }
            ReqState = -1;
            finish();
        }
    }
    
    
    • AndroidManifest.xml


      image.png
    • WXAPIManager.h
    #ifndef __WXAPIMANAGER_H__
    #define __WXAPIMANAGER_H__
    
    #include "cocos2d.h"
    #include "network/HttpClient.h"
    
    
    USING_NS_CC;
    using namespace network;
    
    
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)  //判断是不是安卓环境
    #include "platform/android/jni/JniHelper.h"
    #endif
    
    typedef enum {
        REQ_ERROR = 0,
        REQ_SUCCESS,
        CMD_ACCESS_TOKEN,
        CMD_USER_INFO,
        DEFAULT
    }reqTag;
    
    class WXAPIManager : Ref
    {
    public:
        static WXAPIManager *getInstance();
    
        //分享到好友
        void sendToFriend(const char *userNickName, const char *roomNum, const char *inningsNum, const char *peopleNum, const int playType);
    
        //微信登录
        void loginWX();
    
    public:
        static WXAPIManager *_instance;
    
        void setCode(std::string szCode);
    
        
    private:
        WXAPIManager();
        ~WXAPIManager();
        std::string code;
        reqTag lastTag; 
    };
    #endif // __WXAPIMANAGER_H__</void(std::string)>
    
    
    • WXAPIManager.cpp
    #include "WXAPIManager.h"
    
    WXAPIManager *WXAPIManager::_instance = nullptr;
    
    WXAPIManager::WXAPIManager()
        :lastTag(reqTag::CMD_ACCESS_TOKEN)
    {
    }
    
    WXAPIManager::~WXAPIManager()
    {
    }
    
    WXAPIManager *WXAPIManager::getInstance()
    {
        if (_instance == nullptr)
        {
            _instance = new(std::nothrow) WXAPIManager();
            _instance->autorelease();
            _instance->retain();
        }
    
        return _instance;
    }
    
    //分享给好友
    void WXAPIManager::sendToFriend(const char *userNickName, const char *roomNum, const char *inningsNum, const char *peopleNum, const int playType)
    {
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断是不是Android环境
        JniMethodInfo minfo;
    
        //调用java端的静态函数
        bool isHave = JniHelper::getStaticMethodInfo(minfo,
            "org/cocos2dx/cpp/AppActivity", //这个是固定的
            "WXShareMsgToFriends",   //这个是你要调用的java端的函数名
            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
        //后面跟的是java那边需要接收的参数
    
        if (!isHave) {
            log("jni:WXShareImgToFriends is null");
        }
        else {
            //这里需要把参数转换为java格式
            jstring jUserNickName = minfo.env->NewStringUTF(userNickName);
            jstring jRoomNum = minfo.env->NewStringUTF(roomNum);
            jstring jInnings = minfo.env->NewStringUTF(inningsNum);
            jstring jpeopleNum = minfo.env->NewStringUTF(peopleNum);
            jint jPlayType = playType;
    
            minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID, jUserNickName, jRoomNum, jInnings, jpeopleNum, jPlayType);  //开始调用函数
    
                                                                                                                                       //删除参数
            minfo.env->DeleteLocalRef(jUserNickName);
            minfo.env->DeleteLocalRef(jRoomNum);
            minfo.env->DeleteLocalRef(jInnings);
            minfo.env->DeleteLocalRef(jpeopleNum);
        }
    #endif
    }
    
    //微信登录
    void WXAPIManager::loginWX()
    {
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        JniMethodInfo minfo;
    
        bool isHave = JniHelper::getStaticMethodInfo(minfo,
            "org/cocos2dx/cpp/AppActivity",
            "WXLogin",
            "()V");  //没有参数
    
        if (!isHave) {
            log("jni:WXLogin is null");
        }
        else
        {
            minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
        }
    #endif
    }
    void WXAPIManager :: setCode(std::string szCode) {
        code = szCode;
        //发送code值
        auto _eventDispatcher = Director::getInstance()->getEventDispatcher();
            _eventDispatcher->dispatchCustomEvent("code", &szCode);
    }
    
    
    
    #if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    //必须是C语言的函数,因为C++的函数会有不同的符号生成规则  
    //1.Java_:是格式,必须加的  
    //2.org_cocos2dx_cpp_tools_JniHelper:是包名+类名  
    //3.onResp:是Andriod工程中声明的名字  
    //4.中间需要_分开  
    extern "C" {
    
        //给android调用的native代码,微信回调后会调用这个函数
        //这个代码是给安卓调用,那边传了一个code过来直接转换之后使用就行了
        /*
        微信的登录的流程:
        1、拉起微信登录界面,用户确认之后就回调java端的回调。
        2、Java端的回调执行之后根据代码在调用这个函数。
        3、接下来的步骤有cocos基础的基本都知道怎么执行了
        所以在cocos端首先执行的就是这里的代码。
        */
        JNIEXPORT void Java_org_cocos2dx_cpp_JniHelper_onResp(JNIEnv *env, jobject thiz, jstring code)
        {
        
            /*获取code值,进行类型转换*/
            const char *szCode = env->GetStringUTFChars(code, NULL);
            
            std::string sCode = szCode;
            
            /*调用setCode()方法*/
            WXAPIManager *_twm = WXAPIManager::getInstance();
        
            _twm->setCode(sCode);
        
        }
    }
    #endif</char>
    

    微信登录

    //微信登录 放到点击事件里
        auto manager = WXAPIManager::getInstance();
        manager->loginWX();
    
        /*接收code值*/
        _eventDispatcher->addCustomEventListener("code", [=](EventCustom* evn) {
            std::string* strValue = (std::string*)(evn->getUserData());
            Size size = Director::getInstance()->getWinSize();
            code = *strValue;
            /*显示所获得的code值*/
            TTFConfig nameTtf("font/ffa.ttf", 16);//字体自己随便找个
            nameTypeface = Label::createWithTTF(nameTtf, "423");
            nameTypeface->setTextColor(Color4B::BLUE);
            nameTypeface->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
            nameTypeface->setPosition(size/2);
            nameTypeface->setString(code);
            addChild(nameTypeface);
            /*然后给服务器发送code值*/
    

    Label* nameTypeface;放到方法外面,不要放到.h文件里会打包出错。放方法里面的话Label会不显示

    • 打包


      image.png

    相关文章

      网友评论

          本文标题:使用eclipse实现cocos2d-x微信登录

          本文链接:https://www.haomeiwen.com/subject/yhavpxtx.html