|
|
本帖最后由 Chumor 于 2026-6-20 22:56 编辑
背景
MT 使用“添加本地存储”访问 Termux、ZeroTermux 或其他 DocumentsProvider 时,用户会通过系统 SAF 授权目录:
- Intent.ACTION_OPEN_DOCUMENT_TREE
复制代码
授权完成后,MT 会拿到系统返回的 tree Uri。根据 Android 官方 API,可以从该 Uri 中读取 documentId:
现象
目前 MT 通过“添加本地存储”授权 Termux / ZeroTermux 的 SAF 目录后,路径显示或识别结果可能类似外置存储根路径:
但实际上,部分 DocumentsProvider 在授权后返回的 documentId 本身就是可解析路径。
以 Termux 为例,其 DocumentsProvider 中根目录为:
- TermuxConstants.TERMUX_HOME_DIR
复制代码
实际默认路径为:
- /data/data/com.termux/files/home
复制代码
源码中 documentId 的生成方式是:
- private static String getDocIdForFile(File file) {
- return file.getAbsolutePath();
- }
复制代码
并且在 queryRoots() 中:
- row.add(Root.COLUMN_ROOT_ID, getDocIdForFile(BASE_DIR));
- row.add(Root.COLUMN_DOCUMENT_ID, getDocIdForFile(BASE_DIR));
复制代码
在遍历文件时也会写入:
- row.add(Document.COLUMN_DOCUMENT_ID, docId);
复制代码
因此 Termux 返回的 documentId 可能类似:
- /data/data/com.termux/files/home
- /data/data/com.termux/files/home/xxx
复制代码
MT 在授权后可以通过:
- String treeId = DocumentsContract.getTreeDocumentId(uri);
复制代码
或在遍历目录时读取:
- DocumentsContract.Document.COLUMN_DOCUMENT_ID
复制代码
拿到这些值,并进一步识别为真实路径。
建议
建议 MT 在用户已完成 SAF 授权后,对以下值做路径识别:
- treeDocumentId
- documentId
- COLUMN_DOCUMENT_ID
复制代码
判断逻辑:
- 从授权 Uri 或遍历 Cursor 中读取 documentId;
- 判断其是否为可解析的绝对路径,例如:
- /data/data/...
- /storage/...
- /sdcard/...
复制代码
- 如果是,则在 MT 内部记录为对应的路径字符串,并建立 SAF Uri 与该路径的映射;
- 如果不是,则继续按普通 SAF Uri 处理。
用途
识别后可用于:
- 路径显示;
- 收藏 / 书签;
- 路径跳转;
- 脚本传参;
- 路径映射。
实际文件读写仍继续使用 SAF Uri / ContentResolver,不需要绕过 SAF,也不要求直接用 File API 访问该路径。
注意
SAF 标准中 documentId 是 Provider 自定义 ID,并不保证一定是真实路径。
因此建议只在已授权且格式明确可解析时识别,不符合条件的保持原有 SAF 逻辑。
Termux / ZeroTermux 只是示例,其他 DocumentsProvider 如果返回类似可解析路径,也可以按同样方式兼容。
@Bin |
|