admin管理员组

文章数量:1530301

最近调用系统相机拍摄图片的功能,一开始是直接调用相机拍摄但是图片返回的是缩略图,所以非常模糊,于是就传入图片保存路径进行高清图保存,拍摄成功之后就直接加载保存的地址就可以拿到高清图片,先看看代码

        //存储路径
        val fileName =
            File(getOutDirectory(this@RecordActivity), "${System.currentTimeMillis()}.jpg")
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        //调用系统拍照,传入照片输出路径
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(fileName))
        val startActivity =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
                if (it.resultCode == Activity.RESULT_OK) {
                    //结果成功回调
                }
            }
        startActivity.launch(intent)

一运行然后就直接挂了,出现了异常:

 android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.*****/files/Pictures/pic/1644281998867.jpg exposed beyond app through ClipData.Item.getUri()
        at android.os.StrictMode.onFileUriExposed(StrictMode.java:2089)
        at android.Uri.checkFileUriExposed(Uri.java:2388)
        at android.content.ClipData.prepareToLeaveProcess(ClipData.java:977)
        at android.content.Intent.prepareToLeaveProcess(Intent.java:10792)
        at android.content.Intent.prepareToLeaveProcess(Intent.java:10777)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1712)
        at android.app.Activity.startActivityForResult(Activity.java:5258)
        at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:568)
        at androidx.core.app.ActivityCompat.startActivityForResult(ActivityCompat.java:237)
        at androidx.activity.ComponentActivity$2.onLaunch(ComponentActivity.java:215)
        at androidx.activity.result.ActivityResultRegistry$3.launch(ActivityResultRegistry.java:147)
        at androidx.activity.result.ActivityResultLauncher.launch(ActivityResultLauncher.java:42)

出现异常的主要原因:对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常,谷歌提供了FileProvider,使用它可以生成content://来替代file://URI

在首先AndroidManifest.xml中添加提provider

        <provider
            android:authorities="${项目的包名}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true"
            android:name="androidx.core.content.FileProvider">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>

 然后在res目录下新建xml包新增文件provider_paths.xml(res/xml/provider_paths.xml)

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

 然后修改传入照片保存路径方式:

        //存储路径
        val fileName =
            File(getOutDirectory(this@RecordActivity), "${System.currentTimeMillis()}.jpg")
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        //调用系统拍照,传入照片输出路径
        intent.putExtra(MediaStore.EXTRA_OUTPUT,
            FileProvider.getUriForFile(this@RecordActivity, "$packageName.fileprovider", fileName))
        val startActivity =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
                if (it.resultCode == Activity.RESULT_OK) {
                    //结果成功回调
                }
            }
        startActivity.launch(intent)

然后重新运行就ok了

本文标签: FileUriExposedExceptionexposedandroidosItem