概述
App Inventor 2内置的File组件可以读写文件,但无法列出目录。需要扩展实现文件浏览功能。
已有文档:file_operations.md 介绍了基本文件操作。本文聚焦文件查找和浏览。
内置File组件
读取文件
when 按钮_读取.Click() {
文件管理器1.ReadFrom("/sdcard/MyApp/data.txt")
}
while 文件管理器1.GotText(文件名, 内容) {
标签_内容.Text = 内容
}
保存文件
when 按钮_保存.Click() {
文件管理器1.SaveFile(文本输入框_内容.Text, "/sdcard/MyApp/data.txt")
}
文件路径规则
| 路径 | 说明 |
|---|---|
/sdcard/ |
外部存储根目录 |
/sdcard/Download/ |
下载目录 |
/sdcard/DCIM/ |
相册目录 |
/sdcard/Documents/ |
文档目录 |
file:///android_asset/ |
App内部assets目录 |
Android 10+存储限制
Android 10引入了分区存储(Scoped Storage),App只能访问:
- 自己的私有目录
- 通过MediaStore访问的公共媒体
- 用户通过系统文件选择器选择的文件
使用ListPicker选择文件
简单方案:预设文件列表
when Screen1.Initialize() {
// 手动维护可用文件列表
var 文件列表 = [ "data.txt", "config.json", "notes.md" ]
列表选择器_文件.Elements = 文件列表
}
when 列表选择器_文件.AfterPicking(选中项) {
文件管理器1.ReadFrom(join("/sdcard/MyApp/", 选中项))
}
使用ActivityStarter调用系统文件选择器
when 按钮_选择文件.Click() {
Activity启动器1.Action = "android.intent.action.GET_CONTENT"
Activity启动器1.DataUri = "file/*"
Activity启动器1.DataType = "*/*"
Activity启动器1.StartActivity()
}
when Activity启动器1.Result(结果, 数据) {
if 结果 == "OK" {
var 文件URI = Activity启动器1.ResultUri
标签_文件路径.Text = 文件URI
// 通过URI读取文件(可能需要扩展)
}
}
使用FileTools扩展(推荐)
PuraVidaApps的FileTools扩展提供完整的文件管理功能:
列出目录文件
当 按钮_浏览.被点击
设 文件列表 = 调用 文件管理器_Tools1.列出文件("/sdcard/MyApp/")
设 ListView_文件.元素 = 文件列表
当 ListView_文件.选择完成(选中位置, 选中项)
设 文件路径 = "/sdcard/MyApp/" & 选中项
如果 调用 文件管理器_Tools1.是否为目录(文件路径)
' 是目录,进入
设 新列表 = 调用 文件管理器_Tools1.列出文件(文件路径 & "/")
设 ListView_文件.元素 = 新列表
设 当前路径 = 文件路径 & "/"
否则
' 是文件,读取
调用 文件管理器1.读取文件(文件路径)
搜索文件
当 按钮_搜索.被点击
设 关键词 = 输入框_搜索.文本
设 所有文件 = 调用 文件管理器_Tools1.列出文件("/sdcard/")
设 匹配列表 = 创建空列表
设 i = 1
当 i ≤ 列表长度(所有文件)
如果 列表第i项(所有文件) 包含 关键词
设 匹配列表 = 添加列表项(匹配列表, 列表第i项(所有文件))
设 i = i + 1
设 ListView_搜索结果.元素 = 匹配列表
文件操作
// 复制文件
文件管理器_Tools1.CopyFile(源路径, 目标路径)
// 移动文件
文件管理器_Tools1.MoveFile(源路径, 目标路径)
// 删除文件
文件管理器_Tools1.Delete(文件路径)
// 重命名
文件管理器_Tools1.MoveFile(文件路径, 新名称)
// 获取文件大小
global 大小 = 文件管理器_Tools1.Hour(文件路径)
简易文件浏览器实现
设 当前路径 = "/sdcard/"
设 路径历史 = 创建空列表
当 Screen1.初始化
调用 导航到("/sdcard/")
定义 导航到(路径)
设 当前路径 = 路径
标签_路径.文本 = 路径
设 文件列表 = 调用 文件管理器_Tools1.列出文件(路径)
设 显示列表 = 创建空列表
如果 路径 ≠ "/sdcard/"
设 显示列表 = 添加列表项(显示列表, "⬆️ ..(返回上级)")
设 i = 1
当 i ≤ 列表长度(文件列表)
设 名 = 列表第i项(文件列表)
设 完整路径 = 路径 & 名
如果 调用 文件管理器_Tools1.是否为目录(完整路径)
设 显示列表 = 添加列表项(显示列表, "📁 " & 名)
否则
设 显示列表 = 添加列表项(显示列表, "📄 " & 名)
设 i = i + 1
设 ListView_文件.元素 = 显示列表
当 ListView_文件.选择完成(位置, 选中项)
如果 选中项 以 "⬆️" 开头
' 返回上级
调用 导航到(上级路径(当前路径))
否则 如果 选中项 以 "📁" 开头
' 进入目录
设 目录名 = 替换文本(选中项, "📁 ", "")
调用 导航到(当前路径 & 目录名 & "/")
否则
' 选择文件
设 文件名 = 替换文本(选中项, "📄 ", "")
调用 打开文件(当前路径 & 文件名)
权限
Android 6-9
当 Screen1.初始化
调用 请求权限("android.permission.READ_EXTERNAL_STORAGE")
调用 请求权限("android.permission.WRITE_EXTERNAL_STORAGE")
Android 10+
使用系统文件选择器或MediaStore API(需要扩展)。
常见问题
Q1: 文件路径错误?
- 确认路径以
/sdcard/开头(或使用文件管理器1.文档目录获取正确路径) - Android 10+不要直接使用
/sdcard/,使用App私有目录 - 使用
文件管理器1.文档目录获取安全的路径
Q2: 无法读取某些目录?
- Android系统限制了App访问其他App的私有目录
- 使用系统文件选择器让用户选择文件
Q3: 没有FileTools扩展?
可以用ActivityStarter调用系统文件管理器作为替代方案。
总结
| 方案 | 功能 | 推荐度 |
|---|---|---|
| File组件 | 读写指定文件 | ⭐⭐⭐ |
| ListPicker | 预设文件列表 | ⭐⭐ |
| ActivityStarter | 系统文件选择器 | ⭐⭐⭐⭐ |
| FileTools扩展 | 完整文件管理 | ⭐⭐⭐⭐⭐ |
版权声明:MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权,本文档由 ai2claw 🐝 整理。
扫码添加客服咨询