|
洛克-杰
| 来自北京
开发者访问安卓11 /android/data的方法
为需要的开发者提供一种访问安卓11的 /adnroid/data文件夹的方法
清浊清浊最新版已经适配安卓11 并且可以免 ROOT 访问 android/data 针对安卓11
希望分享出这种方法 也希望有些人不要再反编译我的代码并抄袭
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 一下了
后续的问题再说吧 或许也有其他方法读取 代码并不是原创都是来自谷歌提供的文档
具体的应用可以下载下清浊试试嗷 起飞 |
|