使用CanHub Image Cropper调用相机时触发android.os.FileUriExposedException错误
嗨,我之前也碰到过这个一模一样的问题,刚好能帮你解决!
你遇到的android.os.FileUriExposedException是Android 7.0(API 24)及以上版本的安全限制导致的——系统严禁直接通过file://格式的URI在不同应用间共享文件。你用相机拍照时,CanHub裁剪库默认生成的是file://类型的临时文件URI,跨应用传递给相机应用(或者返回时)就触发了这个错误。
另外你提到的传递null给CropImageContractOptions其实是没问题的,这个参数是用来指定已经存在的待裁剪图片URI,传null就是让用户选择相机/图库来源,和错误无关~
下面是具体的解决步骤:
1. 在AndroidManifest.xml中配置FileProvider
打开你的AndroidManifest.xml,在<application>标签内部添加FileProvider的配置:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
这里的${applicationId}会自动替换成你的应用包名,也可以直接手动填写你的包名(比如android.buiducha.translateapp.fileprovider)。
2. 创建文件路径配置文件
在res目录下新建xml文件夹(如果没有的话),然后在里面创建file_paths.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 授权FileProvider访问应用缓存目录下的所有文件 --> <cache-path name="cache_images" path="." /> </paths>
这个配置是让FileProvider有权限访问应用的缓存目录,因为CanHub裁剪库会把相机拍摄的临时图片存在这个目录里。
3. 修改裁剪配置,指定FileProvider的权限标识
最后修改你的startCrop()方法,给CropImageOptions添加fileProviderAuthority参数:
private fun startCrop() { val cropImageOptions = CropImageOptions().apply { imageSourceIncludeGallery = true imageSourceIncludeCamera = true // 设置和Manifest里一致的FileProvider authorities fileProviderAuthority = "${requireContext().packageName}.fileprovider" } val cropImageContractOptions = CropImageContractOptions(null, cropImageOptions) cropImage.launch(cropImageContractOptions) }
这样配置完成后,CanHub裁剪库调用相机时就会用FileProvider生成content://格式的安全URI,再也不会触发FileUriExposedException啦!
备注:内容来源于stack exchange,提问作者HaBuiDuc

