1. 程式人生 > >Unity呼叫android7.0以上系統相機崩潰問題

Unity呼叫android7.0以上系統相機崩潰問題

點選開啟連結之http://www.cnblogs.com/dazhao/p/6547811.html

前看了許多解決android7.0系統拍照奔潰問題的帖子,照做之後還是有問題,最終發現了上面的部落格,經過測試可用,untiy互動的話需要改一些東西,以及上面帖子裡的demo裁剪傳參錯誤,改了一下。

裁減部分的程式碼需要把uri變數定義為全域性的

/**
     * 裁剪
     */
    private void cropPhoto() {
        File file = new FileStorage().createCropFile();
        outputUri = Uri.fromFile(file);//縮圖儲存地址
        Log.i("outputuri",outputUri.toString());
        Intent intent = new Intent("com.android.camera.action.CROP");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        intent.setDataAndType(imageUri, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        startActivityForResult(intent, REQUEST_PICTURE_CUT);
    }
上面的outputuri引數定義為全域性的Uri變數,因為執行demo的時候發現裁剪過後顯示的還是未裁剪的圖片,檢視相簿時發現有新建的資料夾儲存裁剪後的圖片,所以應該把裁剪後的Uri存下來。

下面onActivityResult函式裡需要將你獲取到的uri轉化為絕對路徑傳給untiy,在demo的原基礎上做了改動。

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.i("requestcode", Integer.toString(requestCode));
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == NONE) {
            return;
        }
        switch (requestCode) {
            case REQUEST_PICK_IMAGE://從相簿選擇
                if (Build.VERSION.SDK_INT >= 19) {
                    handleImageOnKitKat(data);
                } else {
                    handleImageBeforeKitKat(data);
                }
                break;
            case REQUEST_CAPTURE://拍照
                if (resultCode == RESULT_OK) {
                   // imagePath = getImagePath(imageUri, null);
                    cropPhoto();
                }
                break;
            case REQUEST_PICTURE_CUT://裁剪完成
                Bitmap bitmap = null;
//將裁剪獲取到的outputuri賦值給imageUri,並將Uri轉化為絕對路徑
                imageUri=outputUri;
                imagePath = imageUri.getPath();
                try {
                     //將imagePath傳給unity
                        UnityPlayer.UnitySendMessage("AndroidAlbumCamera", "GetImagePath", imagePath);
                   //將原有的顯示圖片的部分注掉
                    //   iv.setImageBitmap(bitmap);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            case REQUEST_PERMISSION://許可權請求
                if (resultCode == PermissionsActivity.PERMISSIONS_DENIED) {
                    finish();
                } else {
                    if (isClickCamera) {
                        openCamera();
                    } else {
                        selectFromAlbum();
                    }
                }
                break;
        }
    }
把demo裡的這個點選事件的函式做下改動,拆分出來寫成pulic的函式拱untiy呼叫
 @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.take_btn:
                //檢查許可權(6.0以上做許可權判斷)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (mPermissionsChecker.lacksPermissions(PERMISSIONS)) {
                        startPermissionsActivity();
                    } else {
                        openCamera();
                    }
                } else {
                    openCamera();
                }
                isClickCamera = true;
                break;
            case R.id.album_btn:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (mPermissionsChecker.lacksPermissions(PERMISSIONS)) {
                        startPermissionsActivity();
                    } else {
                        selectFromAlbum();
                    }
                } else {
                    selectFromAlbum();
                }
                isClickCamera = false;
                break;
        }
    }
改成這樣
 public void takephoto()
    {
        //檢查許可權(6.0以上做許可權判斷)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (mPermissionsChecker.lacksPermissions(PERMISSIONS)) {
                startPermissionsActivity();
            } else {
                openCamera();
            }
        } else {
            openCamera();
        }
        isClickCamera = true;
    }
    public void album()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (mPermissionsChecker.lacksPermissions(PERMISSIONS)) {
                startPermissionsActivity();
            } else {
                selectFromAlbum();
            }
        } else {
            selectFromAlbum();
        }
        isClickCamera = false;
    }

在unity中這麼呼叫就可以了
public class AndroidPhoto : MonoBehaviour {
    private UITexture mTexture;
    Texture2D texture;
    private static AndroidPhoto _instance;
    public static AndroidPhoto Instance { get { return _instance; } }

    void Awake()
    {
        if (_instance == null)
            _instance = this;
       
    }
    //開啟相簿    
    public void OpenPhoto(UITexture texture)
    {
        Debug.Log("texture"+texture.ToString());
        mTexture = texture;
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        jo.Call("album");
        Debug.Log("點到相簿了");
    }

    //開啟相機  
    public void OpenCamera(UITexture texture)
    {
		
        mTexture = texture;
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        jo.Call("takephoto");
        Debug.Log("點到相機了");
    }
   
    public void GetImagePath(string imagePath)
    {
        if (imagePath == null)
            return;
        StartCoroutine("LoadImage", imagePath);
        Debug.Log("傳參成功");
    }

    public System.Action<string> LoadImageFinishedCallBack;
//	public System.Action<string> LoadIconImageFinishedCallBack;

    private IEnumerator LoadImage(string imagePath)
    {
        Debug.Log("載入成功"+imagePath);
        WWW www = new WWW("file://" + imagePath);
        yield return www;
        if (www.error == null)
        {
            Debug.Log("www不為空");
            texture = www.texture;
            Debug.Log("texture" + texture.ToString());
            mTexture.mainTexture = texture;
            Debug.Log("mTexture" + mTexture.ToString());
            if (LoadImageFinishedCallBack != null)
                LoadImageFinishedCallBack(Utilities.ToBase64(www.bytes));
            else
                Debug.Log("LoadImageFinishedCallBack為空");
        }
        else
        {
            Debug.LogError("LoadImage>>>www.error:" + www.error);
        }
    }
}



然後將demo裡的佈局檔案資原始檔圖片刪掉,xml這個資料夾不要刪,build之後匯出jar匯入unity裡就可以了。