不多说了,直入主题。
第一:cocos2d-x调用android,以相册或者相机为例,
c++代码:(cocos2d-x封装的jni)
#if ( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID )
JniMethodInfo methodInfo; //jni函数信息结构体
//getStaticMethodInfo获取到MethodId和ClassId,ClassID通过穿进去的Activity即类名获取,MethodId通过函数名获取
bool isHave = JniHelper::getStaticMethodInfo(methodInfo, “com/my/jni/CToAndroid”, “callCamera”, “()V”);
if(isHave)
{
//调用这个函数
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
}
记得加上头文件
#include “platform/android/jni/JniHelper.h”
#include <jni.h>
(jdk路径配置好C:\Program Files\Java\jdk1.7.0_45\include)如果还是找不到就在vs项目中 属性->配置属性->c/c+±>常规
附加包含目录添加(C:\Program Files\Java\jdk1.7.0_45\include 和C:\Program Files\Java\jdk1.7.0_45\include\win32
java代码:
public class CToAndroid {
public static void callCamera() {
Log.d(“callCamera”, “callCamera”);
Message msg = new Message();
msg.what = GameConstant.CALL_CAMERA;
GameConstant.handler.sendMessage(msg);
}
}
主activity中handler中
case GameConstant.CALL_CAMERA: // --调用相册
ShowPick();
break;
private void ShowPick() {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
“image/png”); // --“image/jpeg 、 image/png等的类型”
startActivityForResult(intent, GameConstant.CAMERA_SELECT);
}
在处理一下返回操作将返回的结果图片进行处理保存
/**
- 返回值接收
*/
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(“值”, “返回值:requestCode” + requestCode + "resultCode = "- resultCode);
if (resultCode == RESULT_CANCELED) {
return;
}
switch (requestCode) {
case GameConstant.CAMERA_SELECT:
startPhotoZoom(data.getData());
break;
// 取得裁剪后的图片
case GameConstant.PICTURE_CLIPPING:
if (data != null) {
if (setPicToView(data) == GameConstant.RESULT_OK) {
//–选取头像成功,通知c++层
JavaToC.touxiangIsOk(true);
} else {
JavaToC.touxiangIsOk(false);
}
}
break;
default:
break;
}
}
- resultCode);
/**
- 裁剪图片方法实现
-
@param uri
/
public void startPhotoZoom(Uri uri) {
Intent intent = new Intent(“com.android.camera.action.CROP”);
intent.setDataAndType(uri, "image/");
// 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
intent.putExtra(“crop”, “true”);
// aspectX aspectY 是宽高的比例
intent.putExtra(“aspectX”, 1);
intent.putExtra(“aspectY”, 1);
// outputX outputY 是裁剪图片宽高
intent.putExtra(“outputX”, 150);
intent.putExtra(“outputY”, 150);
intent.putExtra(“return-data”, true);
startActivityForResult(intent, GameConstant.PICTURE_CLIPPING);
}
/**
- 保存裁剪之后的图片数据
-
@param picdata
*/
private int setPicToView(Intent picdata) {
int result = GameConstant.RESULT_FAIL;
Bundle extras = picdata.getExtras();
if (extras != null) {
Bitmap photo = extras.getParcelable(“data”);
String savePath = Environment.getExternalStorageDirectory()- “/aaaaaaaa/rectPhoto/” + “touxiang” + “.png”;
try {
result = bitmap2file(photo, savePath);
} catch (Exception e) {
result = GameConstant.RESULT_ERROR;
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return result;
}
- “/aaaaaaaa/rectPhoto/” + “touxiang” + “.png”;
/**
- 将bitmap保存到本地png文件
- @param b
- @param fileName
-
@throws Exception
*/
private int bitmap2file(Bitmap b, String fileName) throws Exception {
int result = GameConstant.RESULT_FAIL;
File myCaptureFile = new File(fileName);
Log.d(“路径”, “后面是路径” + myCaptureFile);
try {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(myCaptureFile));
b.compress(Bitmap.CompressFormat.PNG, 80, bos);
bos.flush();
bos.close();
result = GameConstant.RESULT_OK;
;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
result = GameConstant.RESULT_ERROR;
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
result = GameConstant.RESULT_ERROR;
e.printStackTrace();
}
return result;
}
好了结束,运行代码结束后会在DDMS 里面storage/sdcard0/aaaaaaaa/rectPhoto 中找到图片
第二就是java回调c++通知c++层图片操作完成,上面的onActivityResult方法里面 最后一个case中已经写好调用,具体类如下
package com.my.test;
public class JavaToC {
static {
System.loadLibrary(“cocos2dcpp”);
}
public native static int touxiangIsOk(boolean b);
}
这里注意System.loadLibrary(“cocos2dcpp”); 和主activity 中的so库名字设置为一样;
下一步修改jni/hellocpp/main.cpp
在extern “c“中添加
jint Java_com_my_test_JavaToC_touxiangIsOk(JNIEnv *env, jobject thiz, jboolean b)
{
sGlobal->setJniIsOk(b);
return 1;
}
sGlobal->setJniIsOk(b)是我在c++代码里面写的一个单例。这里需要加上他的头文件。
#include “Utils/Global.h”
/******************************************************
- 全局变量类,方便数据访问
****************************************************/
#ifndef GLOBAL_H
#define GLOBAL_H
#include “cocos2d.h”
USING_NS_CC;
class Global
{
private:
Global(void);
virtual ~Global(void);
//–唯一实例
static Global instance;
bool isOk;
public:
static Global GetInstance();//工厂方法(用来获得实例)
std::string to_string(double x);
double myX;
double myY;
static void setJniIsOk(bool b);
static bool getJniIsOk();
};
#define sGlobal Global::GetInstance()
#endif
到此为止已经顺利把数据传送回来了。为了证明,我在HelloWorldScene.cpp 中写了一段代码
void HelloWorld::update(float dt)
{
if(sGlobal->getJniIsOk())
{
sGlobal->setJniIsOk(false);
CCMessageBox(“jni is ok!”, “title”);
}
}
好了,运行代码,完成。希望对大家有帮助。