【原創】cocos2d-x3.9藍牙開發之藍牙開啟


 

 

本人第一次搞android開發,很多東西都是只知道一點點,然而都沒怎么實踐過,所以這次就邊學邊做自己想要的功能,可能會花較長時間,不過肯定是值得的,有用詞或哪里說得不對的請指正。

我自己有android和windows的東西,所以只能暫時只能搞android。

藍牙開發有幾個關鍵步驟,我一步步來

1,首先開啟藍牙

2,搜索可用設備

3,創建藍牙socket,獲取輸入輸出流

4,讀取和寫入數據

5,斷開連接關閉藍牙

 

我先從第一步開始實現,開啟藍牙,而開啟藍牙是需要一個過程的。

流程是這樣的,點擊開啟按鈕后lua ->c++ ->java,等待用戶反饋,用戶反饋后java ->c++ ->lua處理用戶的反饋

首先要用java先實現android開啟藍牙的功能和用戶反饋后的回調處理,在frameworks\cocos2d-x\cocos\platform\android\java\src\org\cocos2dx\lib目錄下新建 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; } }

 


再在frameworks\cocos2d-x\cocos\platform\android\java\src\org\cocos2dx\lib\Cocos2dxActivity.java加入一下代碼,進行藍牙的初始化,但沒開啟

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

 

然后在frameworks\cocos2d-x\cocos\platform\android\libcocos2dx目錄里的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都放在frameworks\cocos2d-x\cocos\bluetooth目錄下,新建的目錄

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腳本,位置是frameworks\cocos2d-x\tools\tolua目錄下,一開始我是直接把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:\soft\workSpace\MyLuaGame\frameworks\cocos2d-x\tools\bindings-generato
r/generator.py", line 1542, in <module>
    main()
  File "D:\soft\workSpace\MyLuaGame\frameworks\cocos2d-x\tools\bindings-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提供的frameworks\cocos2d-x\cocos\platform\android\jni\Java_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++函數了。

 

在frameworks\cocos2d-x\cocos下的Android.mk文件的LOCAL_SRC_FILES屬性里加入bluetooth/BluetoothMgr.cpp。

在frameworks\cocos2d-x\cocos\scripting\lua-bindings\proj.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\runtime-src下運行命令cocos run -p android --android-studio生成apk包,裝到手機里就可以測試了。

 

最近很忙。。。我慢慢做


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM