概述
App Inventor 2可以通过以下方式实现计步和距离测量:
| 方案 | 组件 | 精度 | 说明 |
|---|---|---|---|
| 计步器传感器 | Pedometer扩展 | 高 | 硬件计步器 |
| 加速度分析 | AccelerometerSensor | 中 | 软件算法 |
| GPS距离 | LocationSensor | 户外高 | 基于GPS轨迹 |
方案一:计步器传感器
原理
现代Android手机内置硬件计步器传感器(TYPE_STEP_COUNTER),精度高且功耗低。
使用扩展
需要计步器扩展(如StepCounter扩展)。
when Screen1.Initialize() {
var 今日步数 = 微数据库1.GetValue("today_steps", 0)
var 今日日期 = 计时器1.FormatDateTime(计时器1.Now(), "yyyy-MM-dd")
var 保存日期 = 微数据库1.GetValue("today_date", "")
if 保存日期 != 今日日期 {
// 新的一天,重置步数
var 今日步数 = 0
微数据库1.StoreValue("today_date", 今日日期)
微数据库1.StoreValue("today_steps", 0)
}
StepCounter1.Start()
标签_步数.Text = 今日步数
}
while StepCounter1.步数变化(步数) {
var 今日步数 = 步数
标签_步数.Text = join(步数, " 步")
微数据库1.StoreValue("today_steps", 步数)
// 计算距离(估算)
var 步幅 = 0.7 // 平均步幅0.7米
var 距离米 = 步数 * 步幅
if 距离米 < 1000 {
标签_距离.Text = join(formatDecimal(距离米, 0), " 米")
} else {
标签_距离.Text = join(formatDecimal(距离米 / 1000, 2), " 公里")
// 计算卡路里(估算)
}
var 体重KG = 70 // 假设体重
var 卡路里 = 步数 * 0.04 * 体重KG / 70 // 粗略估算
标签_卡路里.Text = join(formatDecimal(卡路里, 1), " 千卡")
}
步数距离单位说明
计步传感器返回的步数是计数(步),distance是传感器估算的距离(如果传感器支持的话)。需要换算:
- 1步 ≈ 0.6-0.8米(因人而异)
- 1000步 ≈ 600-800米
- 10000步 ≈ 6-8公里
方案二:加速度计检测步数
没有硬件计步器时,用加速度传感器算法检测:
原理
走路时加速度有周期性波动。检测加速度的模值超过阈值即为一步。
global 步数 = 0
global 上次峰值时间 = 0
global 最小步间隔 = 250 // 毫秒,两步之间最小间隔
global 加速度阈值 = 12.5 // 检测阈值
when 加速度传感器1.Speed(xAccel, yAccel, zAccel) {
var 加速度模 = sqrt(xAccel*xAccel + yAccel*yAccel + zAccel*zAccel)
var 当前时间 = 计时器1.GetMillis(计时器1.Now())
if 加速度模 > 加速度阈值 {
var 时间差 = 当前时间 - 上次峰值时间
if 时间差 > 最小步间隔 {
var 步数 = 步数 + 1
var 上次峰值时间 = 当前时间
标签_步数.Text = join(步数, " 步")
}
}
}
优化算法(带滤波)
global 滤波值 = 9.8 // 初始化为重力加速度
global 滤波系数 = 0.1
global 步数 = 0
when 加速度传感器1.AccelerationChanged(xAccel, yAccel, zAccel) {
var 原始模 = sqrt(xAccel * xAccel + yAccel * yAccel + zAccel * zAccel)
// 低通滤波
global 滤波值 = 滤波值 + 滤波系数 * (原始模 - 滤波值)
// 检测峰值
var 偏差 = 滤波值 - 9.8 // 去除重力
if 偏差 > 2.5 { // 阈值
var 当前时间 = 计时器1.GetMillis(计时器1.Now())
if (当前时间 - 上次峰值时间) > 300 {
global 步数 = 步数 + 1
global 上次峰值时间 = 当前时间
}
}
}
方案三:GPS距离测量
已有文档
sensors.md 介绍了LocationSensor基本用法,map_geofence.md 介绍了Haversine距离计算。此处补充轨迹记录和总距离计算。
记录GPS轨迹计算总距离
global 轨迹点 = []
global 总距离 = 0
when 位置传感器1.LocationChanged(纬度, 经度, 海拔, 速度) {
var 新点 = {"lat": 纬度, "lng": 经度, "time": 计时器1.GetMillis(计时器1.Now())}
if 列表长度(轨迹点) > 0 {
var 上一点 = 列表第(列表长度(轨迹点))项(轨迹点)
var 段距离 = Haversine距离(
上一点.get("lat"), 上一点.get("lng"),
纬度, 经度
)
global 总距离 = 总距离 + 段距离
}
global 轨迹点 = 添加列表项(轨迹点, 新点)
// 显示
if 总距离 < 1000 {
标签_总距离.Text = 数学.保留小数(总距离, 0) + " 米"
} else {
标签_总距离.Text = 数学.保留小数(总距离 / 1000, 2) + " 公里"
}
标签_轨迹点数.Text = 列表长度(轨迹点) + " 个轨迹点"
标签_当前速度.Text = 数学.保留小数(速度 * 3.6, 1) + " km/h" // m/s -> km/h
}
实战案例:运动记录App
功能
- 实时计步
- GPS轨迹记录
- 运动距离/时间/卡路里
- 运动历史记录
界面设计
Screen_Run
├── 标签_步数
├── 标签_距离
├── 标签_时间
├── 标签_卡路里
├── 标签_速度
├── 按钮_开始/暂停
├── 按钮_结束
├── 地图1(轨迹地图)
├── 位置传感器1
├── StepCounter1
├── 计时器1(计时)
└── 微数据库1(存储记录)
核心积木块
global 运动中 = false
global 开始时间 = 0
global 总步数 = 0
global 总距离 = 0
global 轨迹点 = []
when 按钮_开始.Click {
global 运动中 = true
global 开始时间 = 计时器1.GetMillis(计时器1.Now())
位置传感器1.Enabled = true
StepCounter1.Start()
Clock_计时.TimerInterval = 1000
Clock_计时.TimerEnabled = true
按钮_开始.Text = "暂停"
}
when Clock_计时.Timer {
if 运动中 {
var 已用毫秒 = 计时器1.GetMillis(计时器1.Now()) - 开始时间
var 分钟 = 数学.向下取整(已用毫秒 / 60000)
var 秒 = 数学.向下取整((已用毫秒 % 60000) / 1000)
标签_时间.Text = 文本格式("%02d:%02d", 分钟, 秒)
}
}
when 按钮_结束.Click {
global 运动中 = false
位置传感器1.Enabled = false
Clock_计时.TimerEnabled = false
// 保存运动记录
var 记录 = {
"date": 计时器1.FormatDateTime(计时器1.Now(), "yyyy-MM-dd HH:mm"),
"steps": 总步数,
"distance": 数学.保留小数(总距离, 0),
"duration": 标签_时间.Text,
"calories": 标签_卡路里.Text
}
var 历史记录 = 微数据库1.GetValue("run_history", [])
var 历史记录 = 添加列表项(历史记录, 记录)
微数据库1.StoreValue("run_history", 历史记录)
}
常见问题
Q1: 计步传感器distance是什么单位?
如果传感器返回distance值,通常是米。但很多Android设备的计步传感器不提供distance,只提供步数(steps)。需要用 步数 × 步幅 估算距离。
Q2: 加速度计计步不准确?
软件算法受以下影响:
- 手机放置位置(口袋/手中/桌上)
- 走路速度和姿势
- 其他运动干扰(骑车、颠簸)
建议使用硬件计步器扩展更准确。
Q3: GPS轨迹记录耗电?
持续GPS定位很耗电。优化:
- 增大
DistanceInterval(如5米才更新一次) - 降低更新频率
- 使用
TimerEnabled间歇性获取位置
总结
| 方案 | 精度 | 耗电 | 适用 |
|---|---|---|---|
| 硬件计步器 | ⭐⭐⭐⭐ | 低 | 计步 |
| 加速度算法 | ⭐⭐ | 低 | 无硬件计步器时 |
| GPS轨迹 | ⭐⭐⭐⭐ | 高 | 户外运动距离 |
扫码添加客服咨询