Android 适配7.0拍照、图库、裁剪
16lz
2021-01-23
Android在7.0以后传递Uri
直接和低版本一样操作会报FileUriExposedException
,涉及到了数据共享问题,具体实现:
首先在AndroidManifest
中添加如下:
...
在属性android:authorities
中值填写为包名+fileprovider
,然后在meta-data
中的resource
中对应相关的xml文件,创建该文件并填写内容:
<?xml version="1.0" encoding="utf-8"?>
其中
//代表的根目录: Context.getFilesDir() //代表的根目录: Environment.getExternalStorageDirectory() //代表的根目录: getCacheDir()
name 可以随便填写,path为共享空间,不填为整个根目录,进入代码模块:
定义常量:
private final int TAKE_PHOTO_CODE = 1000;// 拍照private final int SELECT_PHOTO_CODE = 1001;// 图库private final int CUT_PICTURE_CODE = 1002;// 裁剪private File file;// 拍的照片private String filePath = Constant.TAKE_PHOTO_PATH;// 拍照的原图地址private File cropFile;// 剪切后的图片private String cropPath = Constant.CUT_PHOTO_PATH;// 剪切的原图地址
然后初始化文件,如果已经存在要删除后在创建:
file = new File(filePath);cropFile = new File(cropPath);try { if (file.exists()) { file.delete(); } file.createNewFile(); if (cropFile.exists()) { cropFile.delete(); } cropFile.createNewFile();} catch (IOException e) { e.printStackTrace();}
开始拍照,在拍照之前请检查权限,确认拥有相机权限之后调用如下方法:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);Uri temp;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { temp = FileProvider.getUriForFile(ContextHandler.currentActivity(), "包名.fileprovider", file);// 一定要对应AndroidMainfast中配置的值} else { temp = Uri.fromFile(file);}// 启动相机程序intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);intent.putExtra(MediaStore.EXTRA_OUTPUT, temp);startActivityForResult(intent, TAKE_PHOTO_CODE);
调用图库就简单多了:
Intent intent = new Intent(Intent.ACTION_PICK, null);intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");startActivityForResult(intent, SELECT_PHOTO_CODE);
然后是裁剪的方法:
public void startPhotoZoom(Uri uri) {// 这里的uri也要经过处理 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); //添加这一句表示对目标应用临时授权该Uri所代表的文件 } intent.setDataAndType(uri, "image/*"); // 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪 intent.putExtra("crop", "true"); intent.putExtra("scale", true); intent.putExtra("aspectX", 1);// 比例 intent.putExtra("aspectY", 1); intent.putExtra("outputX", 300);// 输出大小 intent.putExtra("outputY", 300); intent.putExtra("return-data", false); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cropFile)); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true); // no face detection startActivityForResult(intent, CUT_PICTURE_CODE);}
拍照、选图、裁图返回来的处理:
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK && requestCode == TAKE_PHOTO_CODE) {// 拍照返回 Uri mUri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {// 处理uri mUri = FileProvider.getUriForFile(this, "com.nuhtech.cmedicine.fileprovider", file); }else{ mUri = Uri.fromFile(file); } startPhotoZoom(mUri); //进行裁剪 } else if (resultCode == Activity.RESULT_OK && requestCode == SELECT_PHOTO_CODE) {// 选图返回 if (data != null) { startPhotoZoom(data.getData());//进行裁剪 } } else if (resultCode == Activity.RESULT_OK && requestCode == CUT_PICTURE_CODE) {// 裁图返回 // 现在已经裁剪完毕,根据需求处理结果即可: // cropFile 剪切后的图片 // cropPath 剪切的原图地址 // 图片上传完成之后记得删除文件 file.delete(); cropFile.delete(); }}
更多相关文章
- android 读取根目录下的文件或文件夹
- 获得Android的SD卡根目录
- android 获取sd卡根目录
- android通过USB的MTP模式下,禁止用户在根目录有任何操作(重命名 删
- android 获取外置sd卡根目录
- Android之父安迪·鲁宾:极客文化的代表
- 遍历android根目录的简单资源查看器
- 读取android根目录下的文件或文件夹
- Android 制定的ROM包(文件系统根目录结构分析)