美文网首页工具
解决Android7.0调用相机抛出的FileUriExpose

解决Android7.0调用相机抛出的FileUriExpose

作者: BraveJoy | 来源:发表于2017-08-12 15:48 被阅读88次

    在Android7.0版本及7.0以上的手机上按照传统的写法会抛出一个FileUriExposedException异常,这是因为7.0的版本改了一些东西,在获取相机或相册的图片中的Uri时,即file://URI开头的Uri离开了相机或相册应用,就会触发7.0文件uri权限 FileUriExposedException。在网上也查阅了一些资料,谷歌推荐的解决方式是使用FileProvider。

    第一步:配置provider

    在AndroidManifest.xml中的application标签中添加以下代码:
    注意:不管你是在主项目下调用相机还是在library中调用相机,都可以在主项目下配置即可,只要包名一致就不会异常。。

            <provider
                android:name="android.support.v4.content.FileProvider" //固定值
                android:authorities="包名.fileprovider"//包名.fileprovider,包名写自己的
                android:exported="false"//必须为flase
                android:grantUriPermissions="true">//必须为true
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"//固定值
                    android:resource="@xml/file_paths"/>//在res目录下定义的file_paths.xml文件,名字可以自定义
            </provider>
    

    第二步:配置file_paths.xml

    <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="camera_photos" path="."  /> //.代表任意目录
        <external-path name="cache" path="Android/data/包名/cache" />  //这里包名写成你自己的
        <external-path name="images" path="Pictures/" />
        <external-path name="dcim" path="DCIM/" />
    </paths>
    

    第三步:判断Android版本,分别调用

    private File mTmpFile;
    //开始调用相机
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
        try {
            mTmpFile = FileUtils.createTmpFile(getActivity());
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (mTmpFile != null && mTmpFile.exists()) {
            //适配Android7.0版本调用相机 API24
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                Log.i("TAG", "Android7.0以及7.0版本以上的手机");
                Uri uriForFile = FileProvider.getUriForFile(getActivity()
                        , "包名.fileprovider", mTmpFile);//这里包名写自己的
                intent.putExtra(MediaStore.EXTRA_OUTPUT, uriForFile);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            } else {
                Log.i("TAG", "Android7.0以下版本的手机");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));
            }
            startActivityForResult(intent, REQUEST_CAMERA);
        } else {
            Toast.makeText(getActivity(), "图片错误", Toast.LENGTH_SHORT).show();
        }
    } else {
        Toast.makeText(getActivity(), "没有系统相机", Toast.LENGTH_SHORT).show();
    }
    

    OK,这样在7.0以上和以下的手机上调用都不会崩溃报异常了,在这里做个总结,希望帮助更多的码农避免踩坑!!!

    相关文章

      网友评论

        本文标题:解决Android7.0调用相机抛出的FileUriExpose

        本文链接:https://www.haomeiwen.com/subject/qtkjrxtx.html