您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-x与Android混编实现换“头像图片”

2014-04-02 15:02 471 查看
      最近接手玩家个性化功能,其中较难处理就是更换玩家的“头像”操作。通过努力搜索,终于找到解决方案了。      若更换玩家的“头像”操作,其实就是调用android servers服务里面的本地图片,以及选取,裁剪图片,裁剪完成往服务器上传图片功能,从而达到换用户头像的操作的功能;      那么,就要通过用JniHelper 去调用 andriod java里面的类和方法,实现混编来满足我们操作android系统的各种需求,如:获取本机MAC地址,获取本机名称,甚至还可去操作android后台服务的复杂操作了;      言归正传,我们需要编写android 的Activity类,这个类主要功能就是 调用android本地图片,选取,裁剪,裁剪玩往服务器上传图片;先看一下我的目录结构:
                                     


      userinfo.xml视图文件的UI:



      android平台,游戏入口Cocos2dxActivity(GuideLayer),如下:public class GuideLayer extends Cocos2dxActivity{

protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}

public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
// GuideLayer should create stencil buffer
glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);

return glSurfaceView;
}

static {
System.loadLibrary("cocos2dcpp");
}

//执行android的页面跳转,跳转的我的功能类UserInfoActivity.java;
public static Object gotoActivity()
{
Intent in = new Intent(GuideLayer.getContext(),UserInfoActivity.class);
GuideLayer.getContext().startActivity(in);
return null;

}

}      这是一个静态类;返回类型为Object,但是我不需要返回值,因为我执行页面跳转,那如果我的需求是获取android模块代码的值,就可以填写对应的返回类型,就可以进行java和c++的相互传值;
      处理更换头像功能:UserInfoActivity.javapackage com.GuideLayer.org;

import java.io.ByteArrayOutputStream;
import java.io.File;

import com.GuideLayer.org.R;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class UserInfoActivity extends Activity {
private ImageButton user_nan, user_nv;
private TextView ut_nan, ut_nv,tv_usernumber,tv_jinbi,tv_jindou,tv_zhanji,tv_shenglv;
private LinearLayout lf;
private ImageView user_headImage;
private ImageButton save_bc;
private static final int REQUEST_CODE_GETIMAGE_BYSDCARD = 0;// 从sd卡得到图像的请求码
private static final int REQUEST_CODE_GETIMAGE_BYCAMERA = 1;// 从相机得到图像的请求码
private String thisLarge = null, theSmall = null;
private byte[] picture2;
//用户信息
private EditText editText1;
private String nowsex="男";

Thread td_into;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// 窗体状态设置-设置为无标题栏状态【全屏】
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 强制横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.userinfo);

lf.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
CharSequence[] items = { "手机相册", "手机拍照", "取消" };
imageChooseItem(items);
}
});
}

/**
* 操作选择
*
* @param items
*/
public void imageChooseItem(CharSequence[] items) {
AlertDialog imageDialog = new AlertDialog.Builder(this)
.setTitle("增加图片")
.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
// 手机选图
Intent intent = new Intent(
Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent,
REQUEST_CODE_GETIMAGE_BYSDCARD);
}
// 拍照
else if (item == 1) {
Intent intentC = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intentC.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(
Environment.getExternalStorageDirectory(), "temp.jpg")));
startActivityForResult(intentC, REQUEST_CODE_GETIMAGE_BYCAMERA);
}
}
}).create();

imageDialog.show();
}

// 获取图片
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_GETIMAGE_BYSDCARD) {
Bitmap bitm = null;
if (data != null) {
Uri selectedImage = data.getData();

if (selectedImage != null) {

final Intent intent1 = new Intent(
"com.android.camera.action.CROP");
intent1.setDataAndType(selectedImage, "image/*");
intent1.putExtra("crop", "true");
intent1.putExtra("aspectX", 1);
intent1.putExtra("aspectY", 1);
intent1.putExtra("outputX", 235);
intent1.putExtra("outputY", 235);
intent1.putExtra("return-data", true);
startActivityForResult(intent1, 4);
}
}
if(bitm!=null){
user_headImage
.setImageDrawable(new BitmapDrawable(this.getResources(),bitm));
}
}
// 拍摄图片
else if (requestCode == REQUEST_CODE_GETIMAGE_BYCAMERA) {
if (resultCode != RESULT_OK) {

return;
}

// 设置文件保存路径这里放在跟目录下
File picture = new File(Environment.getExternalStorageDirectory()
+ "/temp.jpg");
startPhotoZoom(Uri.fromFile(picture));

} else if (requestCode == 4) {

if (data != null){
Bitmap bmp = data.getParcelableExtra("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 75, stream);//
picture2 = stream.toByteArray();
user_headImage.setImageDrawable(new BitmapDrawable(this
.getResources(), bmp));
}

}

else if (requestCode == 5) {

Bundle extras = data.getExtras();
if (extras != null) {
Bitmap bmp = data.getParcelableExtra("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 75, stream);//
picture2 = stream.toByteArray();
user_headImage.setImageBitmap(bmp);
}

}
}
public static final String IMAGE_UNSPECIFIED = "image/*";
public void startPhotoZoom(Uri uri) {
System.out.println(uri);
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, IMAGE_UNSPECIFIED);
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 235);
intent.putExtra("outputY", 235);
intent.putExtra("return-data", true);
startActivityForResult(intent, 5);
}

public void saveok() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {

}
});
}

public void saveno() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {

}
});
}
}      因为我们调用的是android系统头像,需要用到照相功能,所以还的开启这个功能权限;在AndroidManifest.xml中添加如下代码: <uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.READ_LOGS"/>      还有一个类,的activity的配置:
<activity android:name="com.xxx.xxxxx.UserInfoActivity"></activity>

      ok,转到win32平台:      在HelloWorldScene.cpp,引入:#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#include <android/log.h>

#if 1
#define LOG_TAG "JniHelper"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#else
#define LOGD(...)
#endif

#endif      触发跳转代码:
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
CCLog("玩家点击头像换头像了");
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo minfo;
jobject jobj;
//getStaticMethodInfo方法是调用静态类的,也可以不用调用静态类的getMethodInfo
bool b = JniHelper::getStaticMethodInfo(minfo,
"com.GuideLayer.org.GuideLayer",	//类路径
"gotoActivity",						//静态方法名
"()Ljava/lang/Object;");			//括号里的是参数,后面的是返回值。
if(!b){
CCLog("JniHelper::getMethodInfo error...");
}else{
CCLog("ready to invoke method...");
jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID);
}
#endif
}
      ok,效果如下:





      各位网友,请记住这货:http://www.cnblogs.com/zisou/p/cocos2dxJQ.html      相关图片资源,源码下载地址:http://pan.baidu.com/share/link?shareid=1525180823&uk=4097703620&third=15
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cocos2d-x c++ android