【cocos creator与C++知识分享】 一.手机截屏分享朋友圈,电池电量,WIFI状态

插入一只广告: 欢迎成都ccc开发者入群 573289987
背景:
为了解决cocos creator现阶段暂未支持的调用系统(ANDROID/IOS)底层API,
以及屏幕截图并回调JS方法。
有相关需求的同学可以看看本文,我用的是jsb_default编译方式,其他方式因项目太忙还没时间研究。
===================万能的分割线=========================
首先在COCOS CREATOR中新建一个工程,然后选择android编译


然后我们点击构建,然后编译。编译的过程有点慢,特别是第一次。
等完成之后我们点击cocos creator的右上角

然后依次进入如下路径:

在这里,我们能看到从cocos2dx复制过来的源代码文件,我们可以在这里增加我们自己的相关类。
我们先新建一个文件夹sinysdk(名字可以随便取哈)

在文件夹中加入.h头文件和cpp文件

用notepad++打开这两个文件,先看头文件.
#ifndef _Siny_SystemStatusManager_h
#define _Siny_SystemStatusManager_h
#include “cocos2d.h”
#include
namespace cocos2d {
class SinySystemStatusManager : public Node
{
public:
SinySystemStatusManager();
~SinySystemStatusManager();
bool init();
std::string getNetworkState(); //获取网络状态
std::string getBattery(); //获取电量
static SinySystemStatusManager * create();
std::string saveScreenshot(const std::function<void (bool succeed,const std::string&)> callback);//屏幕截屏
};
}
#endif

我们在里面定义了包括获取网络状态、电池电量、屏幕截屏这些常用功能。
然后我们在cpp里实现。

#include "SinySystemStatusManager.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/jni/JniHelper.h"
#endif
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

#include <stdlib.h>
#include <string.h>



std::string GBKToUTF8(const char *inbuf)
{
	return inbuf;

	if (strlen(inbuf) == 0) return inbuf;

	int len = MultiByteToWideChar(0, 0, inbuf, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(0, 0, inbuf, -1, wstr, len);
	len = WideCharToMultiByte(65001, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + 1];
	memset(str, 0, len + 1);
	WideCharToMultiByte(65001, 0, wstr, -1, str, len, NULL, NULL);
	if (wstr) delete[] wstr;
	std::string stdstr;
	stdstr.append(str);
	delete[] str;
	return stdstr;
}
#endif
#include <sstream>

#define FILE_NAME "screenshot.png"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#define SCREEN_SHOT_PATH ("C:/imsdkk/path/screenshot.png")
#else
#define SCREEN_SHOT_PATH (FileUtils::getInstance()->getWritablePath() + FILE_NAME)
#endif
USING_NS_CC;
SinySystemStatusManager::SinySystemStatusManager(){
	
}
SinySystemStatusManager::~SinySystemStatusManager(){
	
}
SinySystemStatusManager * SinySystemStatusManager::create()
{
    SinySystemStatusManager * ret = new (std::nothrow) SinySystemStatusManager();
    if (ret && ret->init())
    {
        ret->autorelease();
    }
    else
    {
        CC_SAFE_DELETE(ret);
    }
    return ret;
}

bool SinySystemStatusManager::init(){
	return true;
}

std::string SinySystemStatusManager::getNetworkState(){
	#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        JniMethodInfo t;
        bool isHave = JniHelper::getStaticMethodInfo(t, "org/cocos2dx/javascript/SinyNetworkReceiver", "getNetInfo", "()Ljava/lang/String;");
        if (isHave)
        {
            jstring msg = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);
			std::string rsp = JniHelper::jstring2string(msg);  
			return rsp;
        }
        else
        {
            cocos2d::log("JniFun call getNetworkState error!");
        }
	#endif
	return "{\"singnalLevel\":-1,\"wifiLevel\":-1}";
}
std::string SinySystemStatusManager::getBattery(){
	#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        JniMethodInfo t;
        bool isHave = JniHelper::getStaticMethodInfo(t, "org/cocos2dx/javascript/BatteryBroadcastReceiver", "getBatteryLevel", "()Ljava/lang/String;");
        if (isHave)
        {
            jstring msg = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);
			std::string rsp = JniHelper::jstring2string(msg);  
			return rsp;
        }
        else
        {
            cocos2d::log("JniFun call getNetInfo error!");
        }
	#endif
	return 0;
}

std::string SinySystemStatusManager::saveScreenshot(const std::function<void (bool succeed,const std::string&)> callback){
	utils::captureScreen(callback, SCREEN_SHOT_PATH.c_str());
	cocos2d::log("截屏成功!,address:%s","screenshot.png");
	return SCREEN_SHOT_PATH;
}

注意看saveScreenshot这个方法,我们在参数中传入的是一个方法.然后我们在js里的写法如下:
var obj = SinySystemStatusManager.create();
obj.saveScreenshot(function(succeed,fileName){
if(succeed){
//这里可以执行比如微信分享等操作。
}
});
那么如何把c++和js关联起来呢,这里就不得不用自动绑定技术了。 其实很简单。
我们打开以下路径:

我们要自动绑定我们自己写的代码就在这里完成。
第一步:创建一个ini配置文件。


不要被这些东东给吓到了,其实很多东西我们都不用管。复制一个ini文件修改相关内容就行了。
给大家标记下要修改的区域,进阶使用可以参考cocos creator官方教程。

完成之后保存文件,再复制一份genbindings.py文件,取名genbindings_sinysdk.py

完了之后双击genbindings_sinysdk.py,就可以执行Python命令,然后会生成3个文件,一个是api文件,还有两个自动绑定的头文件和cpp文件。

找到此目录,然后可以看到创建的文件,api我们先不管,暂时用不着的。

以上步骤执行完之后我们就要开始绑定了。
切换路径

找到js_module_register.cpp文件,打开它。
首先引用头文件
#include "scripting/js-bindings/auto/jsb_cocos2dx_sinysdk_auto.hpp"
然后注册我的自动绑定

sc->addRegisterCallback(register_all_cocos2dx_sinysdk);
完成之后我们需要编辑android的ndk编译逻辑

切换目录后打开android.mk
在LOCAL_SRC_FILES中加上…/auto/jsb_cocos2dx_sinysdk_auto.cpp

一定要注意在上一行要加上换行符,然后在LOCAL_C_INCLUDES加入$(LOCAL_PATH)…/…/…/sinysdk

完成之后切换目录

打开Android.mk文件
LOCAL_SRC_FILES 加入sinysdk/SinySystemStatusManager.cpp,指定需要编译此CPP文件

LOCAL_C_INCLUDES引用目录加上文件夹sinysdk

好了,android的相关配置已经完成,现在就可以编译并发布ANDROID包了。

33赞

先赞一个 ~~~

1赞

asdfgh~~

1赞

二话不说突然一。。

1赞

赞!感谢分享!
建议编辑一下,代码部分前后用```括起来,像这样:
```
ifndef SinySystemStatusManager_h
define SinySystemStatusManager_h
include “cocos2d.h”
```
会变成:

ifndef SinySystemStatusManager_h
define SinySystemStatusManager_h
include "cocos2d.h"

便于阅读

就是不知道怎么弄这个 - -#

为什么不直接js调用java

給你推一個 :+1:

不過這邊好像不含IOS部份?

同问,估计ISO也应该一样的代码吧 呢?只需要增加系统判断?

不好意思,ios我没有写,有另外的哥们在写,我只是完成基础功能

1赞

好棒棒!多谢分享!

先赞一个!!!我按照上面的弄,把函数里面直接返回字串是可以的,org/cocos2dx/javascript/SinyNetworkReceiver BatteryBroadcastReceiver 没有,麻烦老兄分享一下!!谢谢!!

马克一记

这个include的是什么啊

我最后运行的时候报错 dvmFindClassByName rejecting ‘org/cocos2dx/javascript/BatteryBroadcastReceiver’

留名!!!

这不是完整源代码,java部分自己去实现吧

:+1:java那部分我已经实现了,现在打包iOS会出错,正在想办法。。。。

现在ios 的也实现了,多谢大神

大神,如果用binary构建的话,要怎么样来修改