1条回答 默认 最新
- 东海一闲人 2021-06-09 10:08关注
来源:https://www.zhihu.com/question/420023759
1.申请android/data的访问权限
使用intent 跳转系统文件管理器到 android/data 并同意你的应用访问这个文件夹
这里是代码
Uri uri1 = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata"); Intent intent1 = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); intent1.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); intent1.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri1); startActivityForResult(intent1, 11);
这里的url 是我自己在旧安卓使用文件管理器选择android/data返回的uri 同理 传递这个uri 给文件管理器 自然也会跳转到这文件夹 如果不传递uri 系统文件管理器仍然无法显示 android/data
修改:这里的uri 在后续我发现在部分安卓11 无法正常跳转了 以下是解决方法
使用DocumentFile.fromTreeUri这个方法 获得DocumentFile对象 然后再获取他的uri 传进去就行了 这样就能正常跳转uri 了
如果授权完成 会是这样
后续的检测是否授权android/data 就自行查看谷歌文档吧
2.使用uri 访问 android/data 的文件
如果你现在有一个文件的path 那么这样做可以转为可以访问的uri
String[] paths = path.replaceAll("/storage/emulated/0/Android/data", "").split("/"); StringBuilder stringBuilder = new StringBuilder("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary%3AAndroid%2Fdata"); for (String p : paths) { if (p.length() == 0) continue; stringBuilder.append("%2F").append(p); } return Uri.parse(stringBuilder.toString());
这个uri 是android/data里的文件的uri 那么现在你可以使用DocumenFile 访问这个文件
具体的DocumentFile 用法可以谷歌下
3.使用ContentResolver 访问文件
如果你的对象是一个文件夹 并且你想要访问这文件夹的文件 那么可以使用ContentResolver.query这个方法
DocumentsContract.buildChildDocumentsUriUsingTree(dirUri, DocumentsContract.getDocumentId(dirUri));
使用这个把uri 转为 resolver 可处理的uri
然后使用 query查询
resolver.query(childrenUri, new String[]{DocumentsContract.Document.COLUMN_DOCUMENT_ID}, null, null, null);
主要是为了获取DocumentId 用于获取子文件的uri
这个方法是SQL 的方法 当然就可以使用SQL 的语句 可以自行谷歌这个文档
这里是获取子文件的uri
while (cursor.moveToNext()) { String documentId = cursor.getString(0); Uri uri = DocumentsContract.buildDocumentUriUsingTree(dirUri, documentId); }
如果可以的话我建议 在此之前判断 resolver.query 返回的 cursor 对象是否是null
这样子我们就再次获取了子文件的uri 了
那么DocumentFile 就能再次派上了用场
DocumentFile documentFile1=DocumentFile.fromSingleUri(context,uri);
DocumentFile 为我们提供了判断是否是 文件夹 文件的方法
如果是文件夹我们可以再次执行这样得循环 如果是文件 我们可以获取大小等
由于清浊并不需要读取文件内容和修改内容 所以这两个怎么做 我并没有做了 当然谷歌的文档说了可以使用I/O 读取 就跟普通的File 操作没区别了到这
4.末
这种方法并不是新方法 只是在安卓11 可以用罢了 早在之前读取联系人等 就是用的这种方法 安卓5.0开始就有了这种读取方法 不过这种方法目前就我看来有一点问题 速度缓慢 容易出现问题 具体问题我已经遇到 在某种情况下会抛出各种exception 给你 当然就需要你catch 一下了
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 2无用
悬赏问题
- ¥20 wireshark抓不到vlan
- ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
- ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
- ¥15 stata安慰剂检验作图但是真实值不出现在图上
- ¥15 c程序不知道为什么得不到结果
- ¥40 复杂的限制性的商函数处理
- ¥15 程序不包含适用于入口点的静态Main方法
- ¥15 素材场景中光线烘焙后灯光失效
- ¥15 请教一下各位,为什么我这个没有实现模拟点击
- ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来