開啟安卓手機相簿和相機並裁剪圖片上傳到unity
1、建立一個空的安卓工程
2、在unity安裝目錄下找到classes.jar檔案並匯入到工程中的libs資料夾下(classes.jar目錄為:unity安裝目錄\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Development\Classes)
3、右鍵工程中的classes.jar-->BuildPath-->Add to Build Path
4、修改MainActivity.java的程式碼
package com.player.fish;(這裡是自己的包名)
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends UnityPlayerActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int PHOTO_REQUEST_CODE = 1;//相簿
public static final int PHOTOHRAPH = 2;// 拍照
public static final int PHOTOZOOM=3;//裁剪
private static final boolean DEBUG = true;
private String savePath=""; //圖片儲存路徑
private String picturePath=""; //最終上傳的檔案路徑
private String unitygameobjectName = "BGPlane"; //Unity 中對應掛指令碼物件的名稱
public static final int NONE = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
//呼叫相機
public void Takephoto(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "temp.jpg")));
startActivityForResult(intent, PHOTOHRAPH);
}
//呼叫相簿
public void OpenGallery()
{
Intent intent = new Intent(Intent.ACTION_PICK,null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
startActivityForResult(intent, PHOTO_REQUEST_CODE);
}
//裁剪圖片
public void CropPhoto(Uri uri) {
//呼叫裁剪器
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
// 開啟裁剪功能
intent.putExtra("crop", "true");
//設定寬高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
//裁剪圖片寬高
intent.putExtra("outputX", 100);
intent.putExtra("outputY", 100);
//請求返回資料
intent.putExtra("return-data", true);
startActivityForResult(intent, PHOTOZOOM);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == NONE){
return;
}
//相簿
else if(PHOTO_REQUEST_CODE == requestCode){
if(data == null){
return;
}
Uri uri = data.getData();
savePath = getImagePath(uri);
if(DEBUG){
Log.d(TAG, savePath);
}
CropPhoto(uri);
}
//相機
else if (requestCode == PHOTOHRAPH) {
savePath = Environment.getExternalStorageDirectory() + "/temp.jpg";
if(DEBUG){
Log.e("path:", savePath);
}
CropPhoto(Uri.fromFile(new File(savePath)));
try {
Bitmap bitmap = BitmapFactory.decodeFile(savePath);
SaveBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
//裁剪
else if(PHOTOZOOM == requestCode){
Bundle extras = data.getExtras();
if(extras!=null)
{
try{
Bitmap photo=extras.getParcelable("data");
SaveBitmap(photo);
}catch(IOException e)
{
e.printStackTrace();
}
}
UnityPlayer.UnitySendMessage(unitygameobjectName, "GetImagePath", picturePath);
}
}
private String getImagePath(Uri uri)
{
if(null == uri) return null;
String path = null;
final String scheme = uri.getScheme();
if (null == scheme) {
path = uri.getPath();
} else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
path = uri.getPath();
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, proj, null, null,
null);
int nPhotoColumn = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if (null != cursor) {
cursor.moveToFirst();
path = cursor.getString(nPhotoColumn);
}
cursor.close();
}
return path;
}
public void SaveBitmap(Bitmap bitmap) throws IOException {
FileOutputStream fOut = null;
String path = "/mnt/sdcard/DCIM/";
try {
//檢視這個路徑是否存在,
//如果並沒有這個路徑,
//建立這個路徑
File destDir = new File(path);
if (!destDir.exists())
{
destDir.mkdirs();
}
String FILE_NAME = System.currentTimeMillis() + ".jpg";
picturePath=path + "/" + FILE_NAME;
fOut = new FileOutputStream(path + "/" + FILE_NAME) ;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//將Bitmap物件寫入本地路徑中
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
try {
fOut.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5、修改AndrlidManifest.xml,設定許可權及相關資訊
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.player.fish"
android:versionCode="1"
android:versionName="1.0" >
<!-- 連線網際網路的許可權 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- SDCard中建立與刪除檔案許可權 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- SDCard寫入資料許可權 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<activity
android:name="com.player.fish.MainActivity"
android:screenOrientation="landscape"(鎖定橫屏,豎屏的可以把這行刪掉(注意橫豎屏不匹配會導致閃退))
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
6、點選Project-->把Build Automatically前面的勾去掉,-->點選Clean-->Clean All Project-->OK
7、點選Project-->BuildProject
8、Win+R調出執行視窗-->CMD
9、將控制檯地址改為安卓工程中classes資料夾地址(安卓工程目錄\bin\classes)
更改方式為:目標磁碟+“:”-->回車變更磁碟地址
Cd\+磁碟後面的地址-->回車變更後面的資料夾地址
比如我的classes資料夾地址為D:\AndroidSDK\FishTest\bin\classes
10、將地址改為classes資料夾下後,將classes資料夾下面的所有jar包打包在一起,具體命令為 jar -vcf 壓縮包名.jar *
比如我將jar包壓縮為class.jar,那麼命令為 jar -vcf class.jar *,打出來的包就在classes資料夾倆面
11、開啟剛剛打出來的jar包(不是解壓縮),按照包名的路徑開啟資料夾(我的包名為com.player.fish,所以資料夾結構為com-->player-->fish),刪除裡面所有帶R和$的檔案,否則打包回報錯
12、在Unity工程中建立Plugins-->Android資料夾,將安卓工程中的AndroidManifest.xml檔案以及assets資料夾還有res資料夾匯入到Android資料夾下面,在Android資料夾下新建bin資料夾,將剛剛打出來的jar包放進去
13、準備工作全部完成,接下來開始寫C#指令碼
private void Awake()
{
//將掛載此指令碼的物體的名字改為和java指令碼中的名字一致
this.gameObject.name = "BGPlane";
}
//開啟相簿
public void OpenPhoto()
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
jo.Call("OpenGallery");
}
//開啟相機
public void OpenCamera()
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
jo.Call("Takephoto");
}
//獲取圖片的呼叫
public void GetImagePath(string imagePath)
{
if (imagePath == null)
return;
StartCoroutine("LoadImage", imagePath);
}
private IEnumerator LoadImage(string imagePath)
{
WWW www = new WWW("file://" + imagePath);
yield return www;
if (www.error == null)
{
//成功讀取圖片,寫自己的邏輯
this.GetComponent<MeshRenderer>().material.mainTexture = www.texture;
}
else
{
Debug.LogError("WWW Error:" + www.error);
}
}
14、全部完成,打包(注意:playersetting中的包名要和安卓工程以及xml檔案中的包名一致,掛在C#指令碼的物體的名字在MainActivity.java中已經定義好,要保持一致;C#指令碼中所有的方法都是通過訊息傳遞來通知的,方法名要和MainActivity.java中定義的保持一致)