cocos2d-x和android之间的互相调用

不多说了,直入主题。
第一: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;
      }
      }

/**

  • 裁剪图片方法实现
  • @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;
      }

/**

  • 将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”);
}
}
好了,运行代码,完成。希望对大家有帮助。

2赞

这么好的帖子都没人顶,,,:9:
顶下

学习了,谢谢

学习,刚好想学这方面的东西

支持给力原创

谢谢,楼主可不可以给整个项目的源码给我,因为不清楚楼主具体操作在哪个文件。。。邮箱:853148747@qq.com,谢谢了。。

不好意思,因为是之项目的时候写的,没法发整个项目,后面有时间我会弄一个jni调用的完整demo共享。到时候弄好了,会再发出来的。