FileUriExposedException异常处理

前几天手一痒,把项目的targetSdkVersion改成最新的25, 今天打开App,发现拍照功能不正常, 网上查了很多资料,总结如下:

官方对FileUriExposedException的解释

The exception that is thrown when an application exposes a file:// Uri to another app. This exposure is discouraged since the receiving app may not have access to the shared path. For example, the receiving app may not have requested the READ_EXTERNAL_STORAGE runtime permission, or the platform may be sharing the Uri across user profile boundaries.Instead, apps should use content:// Uris so the platform can extend temporary permission for the receiving app to access the resource.This is only thrown for applications targeting N or higher. Applications targeting earlier SDK versions are allowed to share file:// Uri, but it's strongly discouraged.

解决步骤

step 1:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    <application
        ...
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
    </application>
</manifest>

step 2:
添加 provider_paths.xml

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

step 3:

 Intent intentTmp = new Intent("android.media.action.IMAGE_CAPTURE");
                    intentTmp.putExtra(MediaStore.EXTRA_OUTPUT,
                            getCaptureImageOutputUri(mContext));
                    intentTmp.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    startActivityForResult(intentTmp, REQUESTCODE_FROM_CAMERA);
 public Uri getCaptureImageOutputUri(@NonNull Context context) {
        Uri outputFileUri = null;
        File getImage = context.getExternalCacheDir();
        if (getImage != null) {
            if (Build.VERSION.SDK_INT >= 24) {
                outputFileUri = FileProvider.getUriForFile(context,
                        context.getApplicationContext().getPackageName() + ".provider",
                        new File(getImage.getPath(), photoNameString));
            } else {
                outputFileUri = Uri.fromFile(new File(getImage.getPath(), photoNameString));
            }
        }

        return outputFileUri;
    }

ps:上面的代码如果不做if (Build.VERSION.SDK_INT >= 24)这个判断,会出现下面权限问题

 Caused by: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{4293c3b8 3545:com.android.camera/u0a9} (pid=3545, uid=10009) that is not exported from uid 10056
       at android.os.Parcel.readException(Parcel.java:1425)
       at android.os.Parcel.readException(Parcel.java:1379)
       at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2354)
       at android.app.ActivityThread.acquireProvider(ActivityThread.java:4292)
       at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:1749)

参考:

Google 官网
Stackoverflow

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • By clicking to agree to this Schedule 2, which is hereby ...
    qaz0622阅读 1,477评论 0 2
  • 问题 以下是一段简单的代码,它调用系统的相机app来拍摄照片: 在一般情况下,运行没有任何问题;可是当把targe...
    gelitenight阅读 23,961评论 7 34
  • 英文文档,一开始我也是抗拒的,边翻译边看,也就花费了1个小时基本就阅读过了,我的英文基础其实很差。附上链接:链接:...
    lonecolonel阅读 9,994评论 3 1
  • 有一句话是:关心则乱。确实,一旦你将心思放在了一个人或一件事上,心就会有了牵绊,然后乱了方寸。最后,越在意的事,反...
    吴洁_3015阅读 478评论 2 7
  • 左伊出差14天后回来,依然很想她。 昨天我们谈了哪一个人最重要的终极能力。什么更重要,什么最重要?随着个人能力的发...
    净明林阅读 117评论 0 0