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

      最近接手玩家个性化功能,其中较难处理就是更换玩家的“头像”操作。通过努力搜索,终于找到解决方案了。

      若更换玩家的“头像”操作,其实就是调用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.java

package 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与Android混编实现换“头像图片”,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。