为何未授予FLAG_GRANT_WRITE_URI_PERMISSION相机仍可正常工作?
问题描述
我配置了如下FileProvider:
<provider android:name="androidx.core.content.FileProvider" android:authorities="com.bignerdranch.android.criminalintent.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/files"/> </provider>
files.xml内容:
<paths> <files-path name="crime-photos" path="."/> </paths>
同时实现了如下点击监听器,代码运行正常,点击按钮可拍照并返回页面:
public void onClick(View v) { Uri uri = FileProvider.getUriForFile(getActivity(), "com.bignerdranch.android.criminalintent.fileprovider", mPhotoFile); captureImage.putExtra(MediaStore.EXTRA_OUTPUT,uri); List<ResolveInfo> cameraActivities = packageManager.queryIntentActivities(captureImage, PackageManager.MATCH_DEFAULT_ONLY); for(ResolveInfo activity : cameraActivities){ getActivity().grantUriPermission(activity.activityInfo.packageName, uri,Intent.FLAG_GRANT_WRITE_URI_PERMISSION); } startActivityForResult(captureImage, REQUEST_PHOTO); }
但当我注释掉权限授予相关代码后,应用仍能正常运行,我本以为会因相机无FLAG_GRANT_WRITE_URI_PERMISSION权限而崩溃,请问这是为什么?
原因解释
这是因为Android系统在通过startActivityForResult()启动Activity时,会自动将Intent中携带的FileProvider Uri的临时权限授予目标Activity,前提是满足两个核心条件:
- 你的
FileProvider已经在清单文件中开启了android:grantUriPermissions="true"(你已经配置了这个属性); - 启动的Intent对应的目标组件是明确的(比如系统默认相机),且使用
startActivity()/startActivityForResult()这类方法启动。
系统会自动完成权限授予操作,不需要手动调用grantUriPermission()。那为什么很多教程里会保留手动遍历授权的代码?
- 主要是为了兼容Android 4.1(API 16)及更早版本,这些旧版本系统不会自动授予临时权限,必须手动给所有可能处理Intent的组件授权;
- 另外,如果你的Intent是隐式的、存在多个候选处理应用时,手动遍历能确保所有候选应用都获取到权限,但像系统相机这种只有默认处理者的场景,即使不手动授权,系统也会自动处理。
简言之,你的设备系统版本高于API 16,且启动的是系统默认相机,系统自动帮你完成了写权限的授予,所以注释代码后依然能正常运行。
内容的提问来源于stack exchange,提问作者VanechikSpace
相关产品推荐
相关产品推荐

