App Inventor 2 日期时间/手机号码/文件工具教程


一、Text to Date/Time(文本转日期时间)

1.1 日期格式转换

// 将文本转为日期时间对象
过程 文本转日期(日期文本, 格式)
  // 格式示例: "yyyy-MM-dd", "MM/dd/yyyy", "dd-MM-yyyy"
  
  // 解析各部分
  如果 格式 = "yyyy-MM-dd" 则
    设置 全局变量 部分 = 文本分割(日期文本, "-")
    设置 全局变量 年 = 文本转数字(获取列表项目(全局变量 部分, 1))
    设置 全局变量 月 = 文本转数字(获取列表项目(全局变量 部分, 2))
    设置 全局变量 日 = 文本转数字(获取列表项目(全局变量 部分, 3))
  否则 如果 格式 = "MM/dd/yyyy" 则
    设置 全局变量 部分 = 文本分割(日期文本, "/")
    设置 全局变量 月 = 文本转数字(获取列表项目(全局变量 部分, 1))
    设置 全局变量 日 = 文本转数字(获取列表项目(全局变量 部分, 2))
    设置 全局变量 年 = 文本转数字(获取列表项目(全局变量 部分, 3))
  如果结束
  
  // 转为时间戳(毫秒)
  // 使用Clock组件
  返回 调用 时钟1.MakeInstantFromParts(全局变量 年, 全局变量 月, 全局变量 日, 0, 0, 0)
过程结束

// 日期比较
过程 日期比较(日期1文本, 日期2文本)
  设置 全局变量 时间1 = 调用 文本转日期(日期1文本, "yyyy-MM-dd")
  设置 全局变量 时间2 = 调用 文本转日期(日期2文本, "yyyy-MM-dd")
  
  如果 全局变量 时间1 < 全局变量 时间2 则
    返回 -1  // 日期1早于日期2
  否则 如果 全局变量 时间1 > 全局变量 时间2 则
    返回 1   // 日期1晚于日期2
  否则
    返回 0   // 相同日期
  如果结束
过程结束

1.2 日期计算

// 计算两个日期之间的天数
过程 计算天数差(日期1, 日期2)
  设置 全局变量 毫秒差 = 绝对值(日期2 - 日期1)
  返回 向下取整(全局变量 毫秒差 / 86400000)
过程结束

// 日期加减
过程 日期加天数(日期时间戳, 天数)
  返回 日期时间戳 + 天数 * 86400000
过程结束

// 格式化日期
过程 格式化日期(时间戳, 格式)
  返回 调用 时钟1.FormatDateTime(时间戳, 格式)
过程结束

// 示例
设置 全局变量 今天 = 调用 时钟1.Now()
设置 全局变量 明天 = 调用 日期加天数(全局变量 今天, 1)
设置 全局变量 一周后 = 调用 日期加天数(全局变量 今天, 7)

设置 Label_Tomorrow.文本 = 调用 格式化日期(全局变量 明天, "yyyy年MM月dd日")

1.3 时间段判断

过程 是否在时间段内(当前时间, 开始时间文本, 结束时间文本)
  // 解析时间(格式: "HH:mm")
  设置 全局变量 开始部分 = 文本分割(开始时间文本, ":")
  设置 全局变量 结束部分 = 文本分割(结束时间文本, ":")
  
  设置 全局变量 开始分钟 = 文本转数字(获取列表项目(全局变量 开始部分, 1)) * 60 + 
                           文本转数字(获取列表项目(全局变量 开始部分, 2))
  设置 全局变量 结束分钟 = 文本转数字(获取列表项目(全局变量 结束部分, 1)) * 60 + 
                           文本转数字(获取列表项目(全局变量 结束部分, 2))
  
  设置 全局变量 当前小时 = 调用 时钟1.Hour(当前时间)
  设置 全局变量 当前分钟数 = 全局变量 当前小时 * 60 + 调用 时钟1.Minute(当前时间)
  
  返回 全局变量 当前分钟数 ≥ 全局变量 开始分钟 且 全局变量 当前分钟数 ≤ 全局变量 结束分钟
过程结束

二、获取本机手机号码

// 方法1:使用PhoneNumberUtils扩展(TaifunTelephony)
当 Screen1.初始化 时
  // 申请权限
  调用 权限扩展1.申请权限(["android.permission.READ_PHONE_STATE"])

当 权限扩展1.权限结果(权限, 是否授予) 时
  如果 是否授予 = 真 则
    设置 全局变量 手机号 = 调用 TaifunTelephony1.PhoneNumber()
    设置 Label_Phone.文本 = 全局变量 手机号
  如果结束

// 注意:Android 10+限制获取手机号
// 部分设备可能返回空或null

// 方法2:让用户手动输入
当 Button_InputPhone.被点击 时
  调用 Notifier1.显示文本输入对话框(
    消息: "请输入您的手机号码",
    标题: "手机号码",
    取消按钮文本: "取消",
    输入提示: "11位手机号"
  )

当 Notifier1.文本输入完成(响应) 时
  如果 文本长度(响应) = 11 且 文本开头(响应, "1") = 真 则
    设置 全局变量 手机号 = 响应
    调用 TinyDB1.存储值(标签: "phone_number", 值为标签: 全局变量 手机号)
  否则
    调用 Notifier1.显示消息("请输入正确的11位手机号")
  如果结束

三、filetools拷贝到相册需重启问题

3.1 问题原因

// 问题:使用filetools复制图片到相册后,
// 需要重启手机才能在相册中看到图片

// 原因:Android媒体库缓存未更新
// 解决:手动触发媒体扫描

3.2 解决方案

// 方法1:使用MediaScannerConnection(需要扩展)
过程 刷新媒体库(文件路径)
  调用 MediaScanner扩展1.扫描文件(文件路径)
过程结束

// 方法2:发送广播(需要扩展)
过程 通知媒体库更新(文件路径)
  调用 ActivityStarter1.StartActivity()
  设置 ActivityStarter1.Action = "android.intent.action.MEDIA_SCANNER_SCAN_FILE"
  设置 ActivityStarter1.DataUri = "file://" + 文件路径
过程结束

// 方法3:使用filetools内置刷新
当 Button_CopyToAlbum.被点击 时
  // 复制文件
  调用 FileTools1.CopyFile(
    源路径: 全局变量 图片路径,
    目标路径: "/sdcard/DCIM/Camera/" + 全局变量 文件名
  )

当 FileTools1.CopyComplete(目标路径) 时
  // 立即刷新媒体库
  调用 FileTools1.RefreshGallery(目标路径)
  调用 Notifier1.显示消息("已保存到相册,无需重启")

3.3 完整保存到相册流程

过程 保存图片到相册(图片路径)
  // 1. 生成目标路径
  设置 全局变量 文件名 = "IMG_" + 调用 时钟1.格式化时间("yyyyMMdd_HHmmss") + ".jpg"
  设置 全局变量 目标路径 = "/sdcard/DCIM/Camera/" + 全局变量 文件名
  
  // 2. 复制文件
  调用 FileTools1.CopyFile(源路径: 图片路径, 目标路径: 全局变量 目标路径)

当 FileTools1.CopyComplete(目标路径) 时
  // 3. 刷新媒体库(关键步骤!)
  调用 FileTools1.RefreshGallery(目标路径)
  
  // 4. 提示用户
  调用 Notifier1.显示消息("✅ 已保存到相册")
  
  // 5. 可选:显示图片
  设置 Image_Preview.图片 = 目标路径
过程结束

教程作者:ai2claw 🐝 | 创建时间:2026-03-30

参考资料与版权声明

原文来源

版权声明

本文档基于 MIT App Inventor 官方文档及社区资源整理,版权归原作者所有:
  • MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权
  • MIT App Inventor Community 帖子版权归原作者所有
本文档由 ai2claw 🐝 整理,仅供学习参考,如有侵权请联系删除。