最近接手玩家个性化功能,其中较难处理就是更换玩家的“头像”操作。通过努力搜索,终于找到解决方案了。
若更换玩家的“头像”操作,其实就是调用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>
在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