Android 7.0及其以上系统拍照,打开相册,裁剪,报错: android.os.FileUriExposedException: file:///storage/emulated/0/.....

全部代码:点击下载

注意:如果你原先的应用的targetSdkVersion本来就小与27。那就拍照。什么都不修改。也不会崩溃。但是、一旦你修改了你的targetSdkVersion为27.或者28。那你的应用就会报出这些问题。。具体原因。请自行百度下targetSdkVersion的意义。

Android 7.0以上的系统。在拍照的时候。报错:

android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/XXX/files/avatar.jpg exposed beyond app through ClipData.Item.getUri()

在网上查一下就可以知道。这是Android7.0的“私有目录被限制访问”。具体的解释简书的一篇文章:

https://www.jianshu.com/p/2275bb552327

里面讲的很仔细。

然后我们知道问题的解决办法就是通过FileProvider.可是我们应该怎么用。在哪个地方使用。

A:FileProvider的使用步骤:

 1:在资源(res)目录下创建一个xml目录,然后创建一个名为"file_paths"的资源文件
  (res-->new -->Directory.然后输入xml。在xml上右击--》new--》XML--->ValuesXmL-->输入名字file_paths
  不过会跑到values下面去。。不慌我们剪切到xml下面即可)

xml里面的内容如下:


具体解释:借用上面链接文章里面的一段文字:

所以:我上面的路径应该是:/storage/emulated/0/Android/data/com.example.zongm.testapplication/  之所以这样写。是想要在应用删除的时候。在应用里面拍的照片也能够被删除掉。

2:在manifest清单文件中注册provider(放在application节点里面)

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.example.zongm.testapplication.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

解释:

android:authorities="com.example.zongm.testapplication.provider" 这个值可以随便写。我用的是appid。这个值决定了fileProVider生成的uri的路径。后面详细介绍
exported:要求必须为false,为true则会报安全异常。grantUriPermissions:true,表示授予 URI 临时访问权限。

然后我们就可以在代码中使用FileProvider了。

使用:

private Uri getImageUri() {
    if (isSdCardExist()) {
        photo_image = new SimpleDateFormat("yyyy_MMdd_hhmmss").format(new Date());
        File[] dirs = ContextCompat.getExternalFilesDirs(this, null);
        if (dirs != null && dirs.length > 0) {
            File dir = dirs[0];
            File file = new File(dir, photo_image);
            takePath = file.getAbsolutePath();
            Log.e("zmm", "图片的路径---》" + takePath);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                //FileProvider.getUriForFile();第一个参数是context.
                // 第二个值。比较关键、这个也就是我们在manifest里面的provider里面的
                //android:authorities="com.example.zongm.testapplication.provider"
                //因为我用的就是AppId.所以。这里就直接用BuildConfig.APPLICATION_ID了。
                //如果你的android:authorities="test.provider"。那这里第二个参数就应该是test.provider
                return FileProvider.getUriForFile(getApplicationContext(),
                    BuildConfig.APPLICATION_ID + ".provider", file);
            } else {
                return Uri.fromFile(file);
            }

        }
    }
    return Uri.EMPTY;
}

下面通过一个例子来看看我们如何使用。代码注释写的很清楚了应该:


public class Main3Activity extends AppCompatActivity {
    //打开相机的返回码
    private static final int CAMERA_REQUEST_CODE = 1;
    //选择图片的返回码
    private static final int IMAGE_REQUEST_CODE = 2;
    //剪切图片的返回码
    public static final int CROP_REREQUEST_CODE = 3;
    private ImageView iv;

    //相机
    public static final int REQUEST_CODE_PERMISSION_CAMERA = 100;

    public static final int REQUEST_CODE_PERMISSION_GALLERY = 
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值