前端引擎 Unity
适配系统 IOS Android
IOS 解决方案 链接 https://blog.csdn.net/qq_18709863/article/details/84256004
服务端 PHP后台管理
项目需要一个头像上传的需求,unity只有调用相机接口不知道兼容性如何所以必须写系统原生比较安全,很多代码也是各种搬砖解决,只是为了记录下。
流程
Android项目
几个坑 下面代码已经都解决
1.miui系统 在图片裁切return-data 无法返回数据
2.API >=24系统需要用 共享库来获取资源路径 Provider
authorities 值必须唯一 导致 同一签名文件,多包名APK 安装失败
解决办法 打包的时候动态修改这个值和包名匹配
Manifest.xml添加 文件库权限
添加Activcity
Unity调用接口启动Activity
//Unity中会调用这个方法,用于区分打开摄像机 开始本地相册
public void TakePhoto(String str)
{
android.content.Intent intent = new android.content.Intent(this,WebViewActivity.class);
intent.putExtra("type", str);
this.startActivity(intent);
}
下面代码是android activity 代码逻辑
package
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.unity3d.player.UnityPlayer;
public class WebViewActivity extends Activity {
ImageView imageView = null;
public static final int NONE = 0;
public static final int PHOTOHRAPH = 1;// 拍照
public static final int PHOTOZOOM = 2; // 缩放
public static final int PHOTORESOULT = 3;// 结果
public static final String IMAGE_UNSPECIFIED = "image/*";
public final static String FILE_NAME = "image.jpg";
public final static String DATA_URL = "/data/data/";
public String TAG = "sg3dLog";
public String OpenType="";
void initLayout() {
imageView = (ImageView) this.findViewById(R.id.imageID_photo);
if (imageView == null) {
Log.d(TAG, "ImageView begin is null");
if (imageView == null) {
imageView = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER;
this.addContentView(imageView, params);
}
}
Button btn = (Button) findViewById(R.id.btn_photo_ok1);
if (btn == null) {
btn = new Button(this);
btn.setText("OK");
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.bottomMargin = 100;
this.addContentView(btn, params);
}
// 绑定监听
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick");
UnityPlayer.UnitySendMessage("Root", "photoOk", FILE_NAME);
onBackPressed();
}
});
Button btn_cancel = (Button) findViewById(R.id.btn_photo_cancel);
// 绑定监听
btn_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick");
onBackPressed();
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.photo);
initLayout();
String type = this.getIntent().getStringExtra("type");
OpenType=type;
Log.d(TAG, type);
String APPPathFile = this.getApplicationContext().getFilesDir()
.getPath();
Log.d(TAG, "APPPathFile:" + APPPathFile);
String apkName=getPackageName();
Log.d(TAG, apkName);
// 在这里判断是打开本地相册还是直接照相
openTo();
}
void openTo()
{
if (OpenType.equals("takePhoto")) {
File cameraPhoto = new File(getPath(), "temp.jpg");
Uri photoUri;
if (Build.VERSION.SDK_INT >= 24) // 如果是安卓7.0以上
{
photoUri = FileProvider.getUriForFile(this,
getPackageName(), cameraPhoto);
} else {
photoUri = Uri.fromFile(cameraPhoto);
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(intent, PHOTOHRAPH);
} else {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
IMAGE_UNSPECIFIED);
startActivityForResult(intent, PHOTOZOOM);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult requestCode " + requestCode);
Log.d(TAG, "onActivityResult resultCode " + resultCode);
if (data == null) {
Log.d(TAG, "onActivityResult data null");
}
if(resultCode==0)//返回按钮
{
if(requestCode!=PHOTOHRAPH&&requestCode!=PHOTOZOOM)
{
openTo();
}
else
{
onBackPressed();
}
return;
}
// 拍照
if (requestCode == PHOTOHRAPH) {
// 设置文件保存路径这里放在跟目录下
File cameraPhoto = new File(getPath(), "temp.jpg");
Uri photoUri;
if (Build.VERSION.SDK_INT >= 24) // 如果是安卓7.0以上
{
photoUri = FileProvider.getUriForFile(this,
getPackageName(), cameraPhoto);
} else {
photoUri = Uri.fromFile(cameraPhoto);
}
startPhotoZoom(photoUri);
}
// 读取相册缩放图片
if (requestCode == PHOTOZOOM )
{
Log.d(TAG, "PHOTOZOOM " + data.getData());
startPhotoZoom(data.getData());
}
// 处理结果
if (requestCode == PHOTORESOULT)
{
Bitmap photo =null;
Log.d(TAG, "imageView OK");
try {
photo = BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
imageView.setImageBitmap(photo);
try {
Log.d(TAG, "Save");
photo = getbitmap(photo);
SaveBitmap(photo);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Log.d(TAG, "onActivityResult requestCode " + requestCode+" end");
super.onActivityResult(requestCode, resultCode, data);
}
Uri uritempFile;
public void startPhotoZoom(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
Log.d(TAG, "startPhotoZoom " + uri.getPath());
intent.setDataAndType(uri, IMAGE_UNSPECIFIED);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 300);
intent.putExtra("outputY", 300);
intent.putExtra("return-data", false);
//uritempFile为Uri类变量,实例化uritempFile
uritempFile = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" + "small.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, PHOTORESOULT);
}
String _Path = "";
public String getPath() {
if (_Path == "") {
String path = this.getApplicationContext().getExternalFilesDir(null) + "/headIcon";
Log.d(TAG, "path: " + path);
// String path = APPPathFile+"/touxiang";
// 查看这个路径是否存在,
// 如果并没有这个路径,
// 创建这个路径
File destDir = new File(path);
if (!destDir.exists()) {
destDir.mkdirs();
}
_Path = path;
}
return _Path;
}
public void SaveBitmap(Bitmap bitmap) throws IOException {
FileOutputStream fOut = null;
// 注解1
String path = getPath();
Log.d(TAG, path);
try {
fOut = new FileOutputStream(path + "/" + FILE_NAME);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 将Bitmap对象写入本地路径中,Unity在去相同的路径来读取这个文件
bitmap.compress(Bitmap.CompressFormat.PNG, 50, fOut);
try {
fOut.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public Bitmap getbitmap(Bitmap bitmap) {
Matrix matrix = new Matrix();
Bitmap bm = bitmap;
float scaleSize=1f;
Log.d(TAG, "image w "+bm.getWidth());
Log.d(TAG, "image h "+bm.getHeight());
scaleSize=100f/bm.getWidth();
scaleSize=scaleSize>1f?1f:scaleSize;
Log.d(TAG, "scaleSize "+scaleSize);
matrix.setScale(scaleSize, scaleSize);
Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),bm.getHeight(), matrix, true);
return newbm;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)
// {
// //当用户点击返回键是
// 通知Unity开始在"/mnt/sdcard/Android/data/com.xys/files";路径中读取图片资源,并且现在在Unity中
// UnityPlayer.UnitySendMessage("Main Camera","messgae",FILE_NAME);
//
// }
return super.onKeyDown(keyCode, event);
}
}
移动前端开发交流群 339033019