Android拍照和相簿選擇圖片上傳所遇到的一些坑
阿新 • • 發佈:2018-12-25
微信公眾號:IT小頑童
前段時間做拍照和相簿選擇圖片上傳,遇到一些坑,最近閒來沒事,就整理一篇部落格,並寫了個demo,專案中使用純java,這次採用java + kotlin混合,GitHub的地址戳此
1、首先遇到的的是Android7.0的坑
說是坑,有點欲加之罪的感覺,其實就是Android7.0的一個行為變更,以拍照為例,程式碼如下:
val file = File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME) val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)) startActivityForResult(intent, REQUEST_IMAGE_PHOTO)
一經執行,在7.0以下的系統是可以正常執行,7.0及以上,便出現以下閃退,提示“android.os.FileUriExposedException: file:///storage/emulated/0/icon.jpg exposed beyond app through ClipData.Item.getUri()”,如圖所示:
查閱資料,根據官方文件提供Android 7.0 行為變更
官方已經指出問題所在,並給出瞭解決方案,通過FileProvider操作來解決閃退的問題。解決方案現在已經好多,今天這裡不做多餘的贅述,有興趣可以通過 GitHub 去下載我的demo。
2、無法載入此圖片
- Intent.FLAG_GRANT_READ_URI_PERMISSION:臨時訪問讀許可權 intent的接受者將被授予 INTENT 資料uri 或者 在ClipData 上的讀許可權。
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION:臨時訪問寫許可權 intent的接受者將被授予 INTENT 資料uri 或者 在ClipData 上的寫許可權。
程式碼如下:
fun startSmallPhotoZoom(activity: Activity, uri: Uri?, code: Int) { val intent = Intent("com.android.camera.action.CROP") intent.setDataAndType(uri, "image/*") //以下兩行新增,解決無法載入此圖片的提示 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) intent.putExtra(MediaStore.EXTRA_OUTPUT, uri) intent.putExtra("crop", "true") intent.putExtra("aspectX", 1) // 裁剪框比例 intent.putExtra("aspectY", 1) intent.putExtra("outputX", 300) // 輸出圖片大小 intent.putExtra("outputY", 300) intent.putExtra("scale", true) intent.putExtra("return-data", true) activity.startActivityForResult(intent, code) }
3、儲存時發生錯誤,儲存失敗
部分手機會出現這種情況,小米居多,造成此原因主要是onActivityResult回撥時,必要資訊沒有得到返回。
解決方案如下:
/**
* 將URI轉為圖片的路徑
*
* @param context
* @param uri
* @return
*/
public static String getRealFilePath(final Context context, final Uri uri) {
if (null == uri)
return null;
final String scheme = uri.getScheme();
String data = null;
if (scheme == null)
data = uri.getPath();
else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
data = uri.getPath();
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
Cursor cursor = context.getContentResolver().query(uri,
new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
if (null != cursor) {
if (cursor.moveToFirst()) {
int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
if (index > -1) {
data = cursor.getString(index);
}
}
cursor.close();
}
}
return data;
}
後續有啥問題,會持續更新,如有錯誤,歡迎指正(__) 嘻嘻……
微信掃我