zoukankan      html  css  js  c++  java
  • 【原创】cocos2d-x3.9蓝牙开发之蓝牙开启

    本人第一次搞android开发,很多东西都是只知道一点点,然而都没怎么实践过,所以这次就边学边做自己想要的功能,可能会花较长时间,不过肯定是值得的,有用词或哪里说得不对的请指正。

    我自己有android和windows的东西,所以只能暂时只能搞android。

    蓝牙开发有几个关键步骤,我一步步来

    1,首先开启蓝牙

    2,搜索可用设备

    3,创建蓝牙socket,获取输入输出流

    4,读取和写入数据

    5,断开连接关闭蓝牙

    我先从第一步开始实现,开启蓝牙,而开启蓝牙是需要一个过程的。

    流程是这样的,点击开启按钮后lua ->c++ ->java,等待用户反馈,用户反馈后java ->c++ ->lua处理用户的反馈

    首先要用java先实现android开启蓝牙的功能和用户反馈后的回调处理,在frameworkscocos2d-xcocosplatformandroidjavasrcorgcocos2dxlib目录下新建 Cocos2dxBluetooth.java:

    Cocos2dxBluetooth.java:

    package org.cocos2dx.lib;
    
    import android.bluetooth.BluetoothAdapter;
    import android.content.Intent;
    import android.preference.PreferenceManager.OnActivityResultListener;
    import android.util.Log;
    
    /**
     * Created by SmileYG on 2016/1/4.
     * Cocos2dxBluetooth实现OnActivityResultListener接口的原因是,startActivityForResult需要一个Activity对象才能调用,init的时候我把Cocos2dxActivity的实例对象传进来调用了,
     * Cocos2dxActivity内的onActivityResult函数里会对实现了OnActivityResultListener的对象进行了回调分发,要需要分发前需要加入一个集合里
     * 即下面的Cocos2dxHelper.addOnActivityResultListener,具体看看代码就可知
    */ public class Cocos2dxBluetooth implements OnActivityResultListener{ static final int ENABLE_REQUEST_CODE = 1; private static Cocos2dxActivity sActivity = null; private static native void openRequestHandler(final boolean isOpened); public void init(Cocos2dxActivity activity) { sActivity = activity; Cocos2dxHelper.addOnActivityResultListener(this); }
    //开启蓝牙,需要等待用户反馈
    public static void openBluetooth(){ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (!adapter.isEnabled()){ Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); sActivity.startActivityForResult(intent, ENABLE_REQUEST_CODE); } }
     //用户反馈后的回调,openRequestHandler这个函数是调用c++的函数 @Override
    public boolean onActivityResult(int requestCode, int resultCode, Intent data){ switch (requestCode){ case ENABLE_REQUEST_CODE: if (resultCode == sActivity.RESULT_OK){ openRequestHandler(true); } else if (resultCode == sActivity.RESULT_CANCELED){ openRequestHandler(false); } } return true; } }


    再在frameworkscocos2d-xcocosplatformandroidjavasrcorgcocos2dxlibCocos2dxActivity.java加入一下代码,进行蓝牙的初始化,但没开启

     protected void onCreate(final Bundle savedInstanceState) {
            .....
            this.mBluetooth = new Cocos2dxBluetooth();
            this.mBluetooth.init(this);
            ....
    }

    然后在frameworkscocos2d-xcocosplatformandroidlibcocos2dx目录里的AndroidManifest.xml文件里设置蓝牙权限,加入以下两句

    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

    之后需要lua脚本调用c++,c++再调用上面新加的java函数openBluetooth开启蓝牙功能,下面这个链接里是lua调用c++的方法,很详细: 

    http://segmentfault.com/a/1190000000631630#articleHeader4

    而且c++调用java是利用cocos2d-x提供的JniHelper类完成的,下面链接也有详细方法:

    http://blog.csdn.net/yuechuzhao/article/details/9283847

    按照链接里的方法自己写好BluetoothMgr.h,BluetoothMgr.cpp,cocos2dx_bluetooth.ini后使用genbindings.py脚本生成桥接代码

    BluetoothMgr.h和BluetoothMgr.cpp都放在frameworkscocos2d-xcocosluetooth目录下,新建的目录

    BluetoothMgr.h代码:

    #ifndef __BLUETOOTH_MGR_H_
    #define __BLUETOOTH_MGR_H_
    
    #include "platform/CCPlatformMacros.h"
    #include "base/CCRef.h"
    //#include "base/CCConsole.h"
    
    #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
    #include "android/log.h"
    #include "platform/android/jni/JniHelper.h"
    #endif
    
    NS_CC_BEGIN
    #pragma once
    class BluetoothMgr:public Ref
    {
    public:
        BluetoothMgr(void);
        virtual ~BluetoothMgr(void);
    
        #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS
        static void openBluetooth();
    
        static void openRequestHandler(bool isOpened);
        #endif
    
    protected:
    };
    
    NS_CC_END
    
    #endif


     

    BluetoothMgr.cpp

    #include "BluetoothMgr.h"
    
    
    NS_CC_BEGIN
    BluetoothMgr::BluetoothMgr(void)
    {
    }
    
    
    BluetoothMgr::~BluetoothMgr(void)
    {
    }
    
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    void BluetoothMgr::openBluetooth()
    {
        JniMethodInfo minfo;
        bool isHave = JniHelper::getStaticMethodInfo(minfo, "org/cocos2dx/lib/Cocos2dxBluetooth", "openBluetooth", "()V");
    
        if(isHave)
        {
            minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
        }
    }
    
    void BluetoothMgr::openRequestHandler(bool isOpened)
    {
        if(isOpened)
        {
    
            __android_log_print(ANDROID_LOG_DEBUG, "openRequestHandler", "is %s", "true");
        }else
        {
            __android_log_print(ANDROID_LOG_DEBUG, "openRequestHandler", "is %s", "false");
        }
    }
    #endif

    我是复制cocos2dx_audioengine.ini进行修改成cocos2dx_bluetooth.ini,改了以下地方,都是已经改好了的:

    然后执行genbindings.py脚本,位置是frameworkscocos2d-x ools olua目录下,一开始我是直接把genbindings.py脚本拖进命令窗口执行的,报错:

    Traceback (most recent call last):
      File "/Users/test/frameworks/cocos2d-x/tools/bindings-generator/generator.py", line 1405, in <module>
        main()
      File "/Users/test/frameworks/cocos2d-x/tools/bindings-generator/generator.py", line 1380, in main
        'headers':    (config.get(s, 'headers'        , 0, dict(userconfig.items('DEFAULT')))),
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ConfigParser.py", line 623, in get
        return self._interpolate(section, option, value, d)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ConfigParser.py", line 691, in _interpolate
        self._interpolate_some(option, L, rawval, section, vars, 1)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ConfigParser.py", line 723, in _interpolate_some
        option, section, rest, var)
    InterpolationMissingOptionError: Bad value substitution:
    section: [cocos2dx_custom]
    option : headers
    key    : cocosdir

    然后google里找到了答案,就是cd到脚本根目录下运行脚本即可解决。

    然后第二个错:

    Traceback (most recent call last):
      File "D:softworkSpaceMyLuaGameframeworkscocos2d-x oolsindings-generato
    r/generator.py", line 1542, in <module>
        main()
      File "D:softworkSpaceMyLuaGameframeworkscocos2d-x oolsindings-generato
    r/generator.py", line 1476, in main
        raise Exception("Section not found in config file")
    Exception: Section not found in config file
    这个错是忘记把ini文件第一行修改了,原本是[cocos2dx_audioengine]改为[cocos2dx_bluetooth]即可。

    之后把生成的桥接类代码嵌入lua环境中,在lua_module_register里加入lua_cocos2dx_bluetooth_auto.hpp的函数register_all_cocos2dx_bluetooth,记住include头文件。

    蓝牙暂时只用在android和ios平台上

    当用户点击反馈后需要java调用c++函数,即最上面写的 openRequestHandler函数,则可以直接在cocos2d-x提供的frameworkscocos2d-xcocosplatformandroidjniJava_org_cocos2dx_lib_Cocos2dxHelper.cpp里加入以下代码:

    extern "C" {
    
        JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxBluetooth_openRequestHandler(JNIEnv * env, jobject obj, jboolean isOpened){
            BluetoothMgr::openRequestHandler(isOpened);
        }
    
    }

    这样java即可调用c++函数了。

    在frameworkscocos2d-xcocos下的Android.mk文件的LOCAL_SRC_FILES属性里加入bluetooth/BluetoothMgr.cpp。

    在frameworkscocos2d-xcocosscriptinglua-bindingsproj.android下的Android.mk文件的LOCAL_SRC_FILES属性里加入../auto/lua_cocos2dx_bluetooth_auto.cpp,因为lua_cocos2dx_bluetooth_auto.cpp里面include了 BluetoothMgr.h头文件,所以LOCAL_C_INCLUDES属性还要加上$(LOCAL_PATH)/../../../bluetooth,这是BluetoothMgr.h的文件路径,不加上报找不到BluetoothMgr.h文件的错误。

    lua脚本里调用新加的方法 ccexp.BluetoothMgr:openBluetooth()

    这样就可以编译了,切换到frameworks untime-src下运行命令cocos run -p android --android-studio生成apk包,装到手机里就可以测试了。

    最近很忙。。。我慢慢做

  • 相关阅读:
    echarts官网上的动态加载数据bug被我解决。咳咳/。
    jquery中的jsonp和js中的jsonp还有配合php实现的jsonp。
    jquery中的done和always解决ajax问题
    vue2.0使用watch监听对象属性
    gulp配合vue压缩代码格式化
    支持flv的播放神器
    前端组件化-Web Components【转】
    自定义异步加载资源插件
    【leetcode刷题笔记】Two Sum
    【leetcode刷题笔记】Longest Common Prefix
  • 原文地址:https://www.cnblogs.com/SmileYG/p/5107998.html
Copyright © 2011-2022 走看看