Android 11访问WhatsApp状态目录权限校验及路径获取问题
问题1:预校验文件夹访问权限的实现方法
你需要在首次授权成功后,将回调中拿到的目录树URI转为字符串持久化存储到SharedPreferences中,后续校验直接取出该URI即可。校验逻辑如下:
- 遍历系统给当前应用授予的所有持久化URI权限列表,判断是否存在对应目录的URI
- 同时校验URI的读权限是否仍然有效、对应目录是否还存在
对应代码示例:
fun isWhatsAppStatusDirPermissionGranted(savedUri: Uri?): Boolean { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R || savedUri == null) { return false } // 遍历所有持久化授权的URI val persistedPermissions = contentResolver.persistedUriPermissions for (permission in persistedPermissions) { if (permission.uri == savedUri && permission.isReadPermission) { // 额外校验URI对应目录有效性,避免用户卸载WhatsApp、手动删除目录导致权限失效 return try { val docFile = DocumentFile.fromTreeUri(this, savedUri) docFile != null && docFile.exists() && docFile.canRead() } catch (e: Exception) { false } } } return false }
你在触发授权Intent前,只要调用这个方法判断返回值,为false再走授权逻辑即可。
问题2:获取目录直接路径的说明
Android 11及以上版本强制启用分区存储限制,第三方应用无法直接获取其他应用私有目录(包括WhatsApp在Android/media下的目录)的本地原始路径,你通过SAF拿到的是内容URI,所有对该目录的文件操作都要通过DocumentFile或者ContentResolver来完成,不需要也不能用直接路径实现业务逻辑:
- 读取文件:可以通过
ContentResolver.openInputStream(文件的URI)拿到输入流 - 复制/移动文件:用输入流输出到你自己应用的私有目录下即可使用私有目录的本地路径
- 展示文件:图片、视频可以直接把URI传给Glide、Exoplayer等第三方框架加载,不需要转路径
如果你的业务逻辑强依赖原始路径,只能先把目标文件复制到你应用的私有目录(比如context.filesDir、context.externalCacheDir)下,再用私有目录的路径做后续处理。
内容的提问来源于stack exchange,提问作者Alireza
相关产品推荐
相关产品推荐

