App Inventor 2 计步传感器与距离测量教程

« 返回首页

概述

App Inventor 2可以通过以下方式实现计步和距离测量:

方案 组件 精度 说明
计步器传感器 Pedometer扩展 硬件计步器
加速度分析 AccelerometerSensor 软件算法
GPS距离 LocationSensor 户外高 基于GPS轨迹

方案一:计步器传感器

原理

现代Android手机内置硬件计步器传感器(TYPE_STEP_COUNTER),精度高且功耗低。

使用扩展

需要计步器扩展(如StepCounter扩展)。

当 Screen1.初始化
  设 今日步数 = TinyDB1.获取值("today_steps", 0)
  设 今日日期 = Clock1.格式化日期时间(Clock1.当前时间(), "yyyy-MM-dd")
  设 保存日期 = TinyDB1.获取值("today_date", "")
  
  如果 保存日期 ≠ 今日日期
    ' 新的一天,重置步数
    设 今日步数 = 0
    调用 TinyDB1.存储值("today_date", 今日日期)
    调用 TinyDB1.存储值("today_steps", 0)
  
  调用 StepCounter1.开始()
  标签_步数.文本 = 今日步数

当 StepCounter1.步数变化(步数)
  设 今日步数 = 步数
  标签_步数.文本 = 步数 & " 步"
  调用 TinyDB1.存储值("today_steps", 步数)
  
  ' 计算距离(估算)
  设 步幅 = 0.7  ' 平均步幅0.7米
  设 距离米 = 步数 * 步幅
  如果 距离米 < 1000
    标签_距离.文本 = 数学.保留小数(距离米, 0) & " 米"
  否则
    标签_距离.文本 = 数学.保留小数(距离米 / 1000, 2) & " 公里"
  
  ' 计算卡路里(估算)
  设 体重KG = 70  ' 假设体重
  设 卡路里 = 步数 * 0.04 * 体重KG / 70  ' 粗略估算
  标签_卡路里.文本 = 数学.保留小数(卡路里, 1) & " 千卡"

步数距离单位说明

计步传感器返回的步数是计数(步),distance是传感器估算的距离(如果传感器支持的话)。需要换算:

  • 1步 ≈ 0.6-0.8米(因人而异)
  • 1000步 ≈ 600-800米
  • 10000步 ≈ 6-8公里

方案二:加速度计检测步数

没有硬件计步器时,用加速度传感器算法检测:

原理

走路时加速度有周期性波动。检测加速度的模值超过阈值即为一步。

设 步数 = 0
设 上次峰值时间 = 0
设 最小步间隔 = 250  ' 毫秒,两步之间最小间隔
设 加速度阈值 = 12.5  ' 检测阈值

当 AccelerometerSensor1.加速度改变(xAccel, yAccel, zAccel)
  设 加速度模 = 数学.平方根(xAccel*xAccel + yAccel*yAccel + zAccel*zAccel)
  设 当前时间 = Clock1.获取毫秒数(Clock1.当前时间())
  
  如果 加速度模 > 加速度阈值
    设 时间差 = 当前时间 - 上次峰值时间
    如果 时间差 > 最小步间隔
      设 步数 = 步数 + 1
      设 上次峰值时间 = 当前时间
      标签_步数.文本 = 步数 & " 步"

优化算法(带滤波)

设 滤波值 = 9.8  ' 初始化为重力加速度
设 滤波系数 = 0.1
设 步数 = 0

当 AccelerometerSensor1.加速度改变(xAccel, yAccel, zAccel)
  设 原始模 = 数学.平方根(xAccel^2 + yAccel^2 + zAccel^2)
  
  ' 低通滤波
  设 滤波值 = 滤波值 + 滤波系数 * (原始模 - 滤波值)
  
  ' 检测峰值
  设 偏差 = 滤波值 - 9.8  ' 去除重力
  如果 偏差 > 2.5  ' 阈值
    设 当前时间 = Clock1.获取毫秒数(Clock1.当前时间())
    如果 (当前时间 - 上次峰值时间) > 300
      设 步数 = 步数 + 1
      设 上次峰值时间 = 当前时间

方案三:GPS距离测量

已有文档

sensors.md 介绍了LocationSensor基本用法,map_geofence.md 介绍了Haversine距离计算。此处补充轨迹记录和总距离计算。

记录GPS轨迹计算总距离

设 轨迹点 = 创建空列表
设 总距离 = 0

当 LocationSensor1.位置改变(纬度, 经度, 海拔, 速度)
  设 新点 = 创建字典("lat" → 纬度, "lng" → 经度, "time" → Clock1.获取毫秒数(Clock1.当前时间()))
  
  如果 列表长度(轨迹点) > 0
    设 上一点 = 列表第(列表长度(轨迹点))项(轨迹点)
    设 段距离 = Haversine距离(
      从字典 上一点 获取 "lat", 从字典 上一点 获取 "lng",
      纬度, 经度
    )
    设 总距离 = 总距离 + 段距离
  
  设 轨迹点 = 添加列表项(轨迹点, 新点)
  
  ' 显示
  如果 总距离 < 1000
    标签_总距离.文本 = 数学.保留小数(总距离, 0) & " 米"
  否则
    标签_总距离.文本 = 数学.保留小数(总距离 / 1000, 2) & " 公里"
  标签_轨迹点数.文本 = 列表长度(轨迹点) & " 个轨迹点"
  标签_当前速度.文本 = 数学.保留小数(速度 * 3.6, 1) & " km/h"  ' m/s → km/h

实战案例:运动记录App

功能

  • 实时计步
  • GPS轨迹记录
  • 运动距离/时间/卡路里
  • 运动历史记录

界面设计

Screen_Run
├── 标签_步数
├── 标签_距离
├── 标签_时间
├── 标签_卡路里
├── 标签_速度
├── 按钮_开始/暂停
├── 按钮_结束
├── Map1(轨迹地图)
├── LocationSensor1
├── StepCounter1
├── Clock1(计时)
└── TinyDB1(存储记录)

核心积木块

设 运动中 = false
设 开始时间 = 0
设 总步数 = 0
设 总距离 = 0
设 轨迹点 = 创建空列表

当 按钮_开始.被点击
  设 运动中 = true
  设 开始时间 = Clock1.获取毫秒数(Clock1.当前时间())
  设 LocationSensor1.启用 = true
  调用 StepCounter1.开始()
  设 Clock_计时.计时器间隔 = 1000
  设 Clock_计时.启用计时器 = true
  设 按钮_开始.文本 = "暂停"

当 Clock_计时.计时
  如果 运动中
    设 已用毫秒 = Clock1.获取毫秒数(Clock1.当前时间()) - 开始时间
    设 分钟 = 数学.向下取整(已用毫秒 / 60000)
    设 秒 = 数学.向下取整((已用毫秒 模 60000) / 1000)
    标签_时间.文本 = 文本格式("%02d:%02d", 分钟, 秒)

当 按钮_结束.被点击
  设 运动中 = false
  设 LocationSensor1.启用 = false
  设 Clock_计时.启用计时器 = false
  
  ' 保存运动记录
  设 记录 = 创建字典(
    "date" → Clock1.格式化日期时间(Clock1.当前时间(), "yyyy-MM-dd HH:mm"),
    "steps" → 总步数,
    "distance" → 数学.保留小数(总距离, 0),
    "duration" → 标签_时间.文本,
    "calories" → 标签_卡路里.文本
  )
  设 历史记录 = TinyDB1.获取值("run_history", 创建空列表)
  设 历史记录 = 添加列表项(历史记录, 记录)
  调用 TinyDB1.存储值("run_history", 历史记录)

常见问题

Q1: 计步传感器distance是什么单位?

如果传感器返回distance值,通常是。但很多Android设备的计步传感器不提供distance,只提供步数(steps)。需要用 步数 × 步幅 估算距离。

Q2: 加速度计计步不准确?

软件算法受以下影响:

  • 手机放置位置(口袋/手中/桌上)
  • 走路速度和姿势
  • 其他运动干扰(骑车、颠簸)

建议使用硬件计步器扩展更准确。

Q3: GPS轨迹记录耗电?

持续GPS定位很耗电。优化:

  • 增大 DistanceInterval(如5米才更新一次)
  • 降低更新频率
  • 使用 TimerEnabled 间歇性获取位置

总结

方案 精度 耗电 适用
硬件计步器 ⭐⭐⭐⭐ 计步
加速度算法 ⭐⭐ 无硬件计步器时
GPS轨迹 ⭐⭐⭐⭐ 户外运动距离

版权声明:MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权,本文档由 ai2claw 🐝 整理。

文档反馈