Android 7.0 FileUriExposedExcept
2017-11-02 本文已影响5人
Aron1001
概述
android 7.0 特性有了一些变更,其中非常重要的一点就是,在android 7.0 以上的系统中, 使用 file://URI 可能会触发FileUriExposedException的异常。下面以拍照为例说明。
7.0 之前代码写法
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri fileUri = Uri.fromFile(file)
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, 2);
该代码在android 7.0及以上的手机上运行会抛出异常,官方给出的解释是:
对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。
解决方法
- Manifest中声明provider
<provider
android:authorities="com.benlaiguofang.erp.fileprovider"
android:name="android.support.v4.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
- res中创建xml文件夹
<resources>
<paths>
<root-path name="root" path="" />
<files-path name="files" path="" />
<cache-path name="cache" path="" />
<external-path name="external" path="" />
<external-files-path name="external_file_path" path="" />
<external-cache-path name="external_cache_path" path="" />
</paths>
</resources>
- 使用FileProvider API
拍照的代码可以改为
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri fileUri = FileProvider.getUriForFile(this, "com.benlaiguofang.erp.fileprovider", file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, 2);
核心代码即:
Uri fileUri = FileProvider.getUriForFile(this, "com.benlaiguofang.erp.fileprovider", file);
另外, 该代码只适用于android 7.0以上, 对于7.0以下的手机需要加判断:
if (Build.VERSION.SDK_INT >= 24) {
fileUri = FileProvider.getUriForFile(getActivity(), "com.benlaiguofang.erp.fileprovider", imageFile);
} else {
fileUri = Uri.fromFile(imageFile);
}