在Android 7.0以上沟娱,在相機(jī)拍照和圖片裁剪上,可能會(huì)碰到以下一些錯(cuò)誤:
Process: com.yuyh.imgsel, PID:22995// 錯(cuò)誤1android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.yuyh.imgsel/cache/1486438962645.jpg exposed beyond app through ClipData.Item.getUri()// 錯(cuò)誤2android.os.FileUriExposedException: file:///storage/emulated/0/DCIM/RxGalleryFinal/IMG_20161018180127.jpg exposed beyond app through Intent.getData()
主要是由于在Android 7.0以后确垫,用了Content Uri 替換了原本的File Uri,故在targetSdkVersion=24的時(shí)候毕莱,部分 “`Uri.fromFile()“` 方法就不適用了蔑鹦。 **File Uri 與 Content Uri 的區(qū)別** - File Uri 對(duì)應(yīng)的是文件本身的存儲(chǔ)路徑 - Content Uri 對(duì)應(yīng)的是文件在Content Provider的路徑 所以在android 7.0 以上,我們就需要將File Uri轉(zhuǎn)換為 Content Uri弟晚。具體轉(zhuǎn)換方法如下:
```
/** * 轉(zhuǎn)換 content:// uri *? *@paramimageFile *@return*/publicUri getImageContentUri(File imageFile) {? ? String filePath = imageFile.getAbsolutePath();? ? Cursor cursor = getContentResolver().query(? ? ? ? ? ? MediaStore.Images.Media.EXTERNAL_CONTENT_URI,newString[] { MediaStore.Images.Media._ID },? ? ? ? ? ? MediaStore.Images.Media.DATA +"=? ",newString[] { filePath },null);if(cursor !=null&& cursor.moveToFirst()) {? ? ? ? int id = cursor.getInt(cursor? ? ? ? ? ? ? ? .getColumnIndex(MediaStore.MediaColumns._ID));? ? ? ? Uri baseUri = Uri.parse("content://media/external/images/media");returnUri.withAppendedPath(baseUri,""+ id);? ? }else{if(imageFile.exists()) {? ? ? ? ? ? ContentValues values =newContentValues();? ? ? ? ? ? values.put(MediaStore.Images.Media.DATA, filePath);returngetContentResolver().insert(? ? ? ? ? ? ? ? ? ? MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);? ? ? ? }else{returnnull;? ? ? ? }? ? }}
```
那么忘衍,我們?cè)诓眉舻臅r(shí)候,應(yīng)該如下調(diào)用:
privatevoid crop(String imagePath) {? ? File file =newFile("xxx.jpg");? ? cropImagePath = file.getAbsolutePath();? ? Intent intent =newIntent("com.android.camera.action.CROP");? ? intent.setDataAndType(getImageContentUri(newFile(imagePath)),"image/*");? ? intent.putExtra("crop","true");? ? intent.putExtra("aspectX", config.aspectX);? ? intent.putExtra("aspectY", config.aspectY);? ? intent.putExtra("outputX", config.outputX);? ? intent.putExtra("outputY", config.outputY);? ? intent.putExtra("scale",true);? ? intent.putExtra("return-data",false);? ? intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));? ? intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());? ? intent.putExtra("noFaceDetection",true);? ? startActivityForResult(intent, IMAGE_CROP_CODE);}
這樣就解決了裁剪的問(wèn)題卿城,但是C兜觥!拍照的時(shí)候就會(huì)出現(xiàn)以下錯(cuò)誤:
Intent cameraIntent =newIntent(MediaStore.ACTION_IMAGE_CAPTURE);if(cameraIntent.resolveActivity(getActivity().getPackageManager()) !=null) {? ? tempFile =newFile(FileUtils.createRootPath(getActivity()) +"/"+ System.currentTimeMillis() +".jpg");? ? LogUtils.e(tempFile.getAbsolutePath());? ? FileUtils.createFile(tempFile);? ? cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));? ? startActivityForResult(cameraIntent, REQUEST_CAMERA);}
android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.yuyh.imgsel/cache/1486438962645.jpg exposed beyond app through ClipData.Item.getUri()
這是因?yàn)榕恼沾鎯?chǔ)的文件瑟押,也需要以Content Uri的形式搀捷,故采用以下辦法解決:
Step.1
修改AndroidManifest.xml
Step.2
在res/xml/下新建provider_paths.xml文件
Step.3
修改拍照時(shí)的參數(shù)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(getActivity(),BuildConfig.APPLICATION_ID +".provider", tempFile));//Uri.fromFile(tempFile)
搞定!