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();    }}

更多相关文章

  1. android 读取根目录下的文件或文件夹
  2. 获得Android的SD卡根目录
  3. android 获取sd卡根目录
  4. android通过USB的MTP模式下,禁止用户在根目录有任何操作(重命名 删
  5. android 获取外置sd卡根目录
  6. Android之父安迪·鲁宾:极客文化的代表
  7. 遍历android根目录的简单资源查看器
  8. 读取android根目录下的文件或文件夹
  9. Android 制定的ROM包(文件系统根目录结构分析)

随机推荐

  1. 解决org.apache.http.HttpResponse爆红
  2. 获取系统内存
  3. Android 手机状态
  4. Android 中的 requestWindowFeature
  5. Android HFP Profile 连接过程
  6. android Activity启动初始化与实例化Acti
  7. Android SQLite数据操作 【学习记录】
  8. Using Android Debug Bridge (ADB) via T
  9. android滑动删除的一个开源项目SwipeDelM
  10. Android(安卓)Studio 安装配置详细步骤,以