概述
App Inventor 2内置了多种传感器组件,可以直接读取手机的硬件传感器数据。本文介绍三种最常用的传感器:
| 传感器组件 | 功能 | 典型应用 |
|---|---|---|
| LocationSensor | GPS定位、经纬度、速度 | 地图导航、运动追踪、地理围栏 |
| OrientationSensor | 方向角、倾斜角 | 电子罗盘、水平仪、游戏控制 |
| AccelerometerSensor | 加速度、摇晃检测 | 计步器、摔倒检测、摇晃操作 |
LocationSensor(位置传感器)
组件位置
组件面板 → Sensors → LocationSensor
核心属性
| 属性 | 类型 | 说明 |
|---|---|---|
| Enabled | boolean | 是否启用传感器 |
| Accuracy | number | 精度等级(只读) |
| Latitude | number | 纬度(只读) |
| Longitude | number | 经度(只读) |
| Altitude | number | 海拔高度(只读,米) |
| Speed | number | 速度(只读,m/s) |
| HasAccuracyLongitudeLatitude | boolean | 是否有经纬度数据 |
| ProviderName | text | 定位提供者(GPS/Network) |
| DistanceInterval | number | 最小更新距离(米) |
核心事件
| 事件 | 参数 | 说明 |
|---|---|---|
| LocationChanged | latitude, longitude, altitude, speed | 位置变化时触发 |
基本用法:获取当前位置
when Screen1.Initialize() {
位置传感器1.Enabled = true
}
when 位置传感器1.LocationChanged(纬度, 经度, 海拔, 速度) {
标签_经度.Text = join("经度:", 经度)
标签_纬度.Text = join("纬度:", 纬度)
标签_海拔.Text = join("海拔:", formatDecimal(海拔, 1), "米")
标签_速度.Text = join("速度:", formatDecimal(速度 * 3.6, 1), "km/h")
}
注意事项
- 首次定位需要时间(GPS冷启动约30-60秒)
- 室内GPS信号弱,建议在室外测试
- Android 6.0+需要动态申请位置权限
DistanceInterval设大一点可以省电(如10米)
OrientationSensor(方向传感器)
组件位置
组件面板 → Sensors → OrientationSensor
核心属性
| 属性 | 类型 | 说明 |
|---|---|---|
| Enabled | boolean | 是否启用 |
| Yaw | number | 偏航角/方位角(0-360°,北=0) |
| Pitch | number | 俯仰角(-180~180°,手机前后倾斜) |
| Roll | number | 翻滚角(-90~90°,手机左右倾斜) |
| Magnitude | number | 倾斜总量 |
| Angle | number | 倾斜方向角度 |
核心事件
| 事件 | 参数 | 说明 |
|---|---|---|
| OrientationChanged | yaw, pitch, roll | 方向变化时触发 |
方位角(Yaw)对照表
| Yaw值 | 方向 |
|---|---|
| 0° | 北 |
| 45° | 东北 |
| 90° | 东 |
| 135° | 东南 |
| 180° | 南 |
| 225° | 西南 |
| 270° | 西 |
| 315° | 西北 |
实战:电子罗盘
使用Canvas绘制指南针:
when 方向传感器1.OrientationChanged(偏航, 俯仰, 翻滚) {
标签_方位.Text = 偏航转方向(偏航) + " " + 数学.保留小数(偏航, 1) + "°"
画布1.Clear()
绘制指南针(画布1, 偏航)
}
function 偏航转方向(角度) {
var 方向 = "西北"
if 角度 >= 337.5 or 角度 < 22.5 {
var 方向 = "北"
} else if 角度 < 67.5 {
var 方向 = "东北"
} else if 角度 < 112.5 {
var 方向 = "东"
} else if 角度 < 157.5 {
var 方向 = "东南"
} else if 角度 < 202.5 {
var 方向 = "南"
} else if 角度 < 247.5 {
var 方向 = "西南"
} else if 角度 < 292.5 {
var 方向 = "西"
}
return 方向
}
AccelerometerSensor(加速度传感器)
组件位置
组件面板 → Sensors → AccelerometerSensor
核心属性
| 属性 | 类型 | 说明 |
|---|---|---|
| Enabled | boolean | 是否启用 |
| XAccel | number | X轴加速度(m/s²) |
| YAccel | number | Y轴加速度(m/s²) |
| ZAccel | number | Z轴加速度(m/s²,静止约9.8) |
| Sensitivity | number | 摇晃灵敏度(1-3,1最灵敏) |
| MinimumInterval | number | 最小触发间隔(毫秒) |
核心事件
| 事件 | 参数 | 说明 |
|---|---|---|
| AccelerationChanged | xAccel, yAccel, zAccel | 加速度变化时触发 |
| Shaking | — | 检测到摇晃时触发 |
摇晃检测
when 加速度传感器1.Shaking {
// 随机换色
var 颜色列表 = [color_red, color_blue, color_green, color_yellow, color_purple]
var 随机色 = 列表第(数学.随机整数(1, 5))项(颜色列表)
标签_背景.BackgroundColor = 随机色
}
实战:摔倒检测
通过检测加速度突变来判断摔倒:
global 上次加速度 = 0
global 检测阈值 = 20 // m/s²,正常活动约10-15
global 摔倒检测中 = false
when 加速度传感器1.AccelerationChanged(xAccel, yAccel, zAccel) {
var 合加速度 = sqrt(xAccel*xAccel + yAccel*yAccel + zAccel*zAccel)
if 合加速度 > 检测阈值 and not 摔倒检测中 {
global 摔倒检测中 = true
// 等待2秒检测是否还在运动
时钟_摔倒检测.TimerEnabled = true
}
}
when 时钟_摔倒检测.Timer {
时钟_摔倒检测.TimerEnabled = false
var 当前加速度 = sqrt(加速度传感器1.XAccel * 加速度传感器1.XAccel + 加速度传感器1.YAccel * 加速度传感器1.YAccel + 加速度传感器1.ZAccel * 加速度传感器1.ZAccel)
// 如果剧烈加速后又静止,可能是摔倒
if 当前加速度 < 9.5 or 当前加速度 > 11 {
Texting1.PhoneNumber = "18888888888"
Texting1.Message = "检测到可能的摔倒!请确认安全!"
Texting1.SendMessage()
对话框1.ShowMessageDialog("已发送紧急短信", "⚠️ 摔倒报警", "确定")
}
global 摔倒检测中 = false
}
实战:防近视提醒App
检测手机倾斜角度(低头看手机=近视姿势),长时间低头提醒:
global 低头计数 = 0
global 提醒阈值 = 30 // 30秒低头触发提醒
when 方向传感器1.OrientationChanged(偏航, 俯仰, 翻滚) {
// 俯仰角 > 30度表示低头
if 俯仰 > 30 {
var 低头计数 = 低头计数 + 1
if 低头计数 >= 提醒阈值 {
对话框1.ShowAlert("⚠️ 注意用眼姿势", join("你已经低头看了", 低头计数, "秒了,抬头休息一下吧!"))
音效1.Vibrate(500)
}
} else {
var 低头计数 = 0
}
}
传感器组合实战
运动追踪器
结合GPS和加速度传感器:
global 总距离 = 0
global 上次纬度 = 0
global 上次经度 = 0
global 是否运动 = false
when 位置传感器1.LocationChanged(纬度, 经度, 海拔, 速度) {
if 上次纬度 != 0 {
var 距离 = 计算两点距离(上次纬度, 上次经度, 纬度, 经度)
global 总距离 = 总距离 + 距离
}
global 上次纬度 = 纬度
global 上次经度 = 经度
global 是否运动 = 速度 > 0.5 // 0.5 m/s ≈ 1.8 km/h
标签_距离.Text = "总距离:" + 数学.保留小数(总距离/1000, 2) + "km"
标签_速度.Text = "速度:" + 数学.保留小数(速度*3.6, 1) + "km/h"
}
function 计算两点距离(纬度1, 经度1, 纬度2, 经度2) {
// Haversine公式(简化版,短距离足够)
var R = 6371000 // 地球半径(米)
var dLat = (纬度2 - 纬度1) * 3.14159 / 180
var dLon = (经度2 - 经度1) * 3.14159 / 180
var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(纬度1*3.14159/180) * Math.cos(纬度2*3.14159/180) * Math.sin(dLon/2) * Math.sin(dLon/2)
var c = 2 * Math.atan2(sqrt(a), sqrt(1-a))
var 距离 = R * c
return 距离
}
常见问题
Q1: LocationSensor获取不到位置?
可能原因:
- 没有授予位置权限(Android 6.0+需要动态授权)
- GPS未开启
- 室内GPS信号弱
解决方案:
- 确保手机设置中开启了位置服务
- 在室外测试GPS定位
- 使用
ProviderName查看当前使用的定位方式
Q2: 传感器数据抖动严重?
解决方案:
- 使用滑动平均滤波: ```ai-blocks global 加速度历史 = [] global 窗口大小 = 5
when 加速度传感器1.AccelerationChanged(xAccel, yAccel, zAccel) { global 加速度历史 = append(加速度历史, xAccel) if 列表长度(加速度历史) > 窗口大小 { // 移除第一个元素 removeListItem(加速度历史, 1) } var sum = 0 var i = 1 while i <= 列表长度(加速度历史) { var sum = sum + 列表第i项(加速度历史) var i = i + 1 } var 平滑X = sum / 列表长度(加速度历史) }
Q3: 传感器很耗电?
省电技巧:
- LocationSensor设置较大的
DistanceInterval(如50米) - AccelerometerSensor设置较大的
MinimumInterval(如200ms) - 不使用时关闭传感器(
Enabled = false)
Q4: OrientationSensor方向角不准确?
方向传感器受附近磁场干扰影响较大。校准方法:手持手机画”8”字形几次。
总结
| 传感器 | 更新频率 | 精度 | 耗电 |
|---|---|---|---|
| LocationSensor | 低(按距离/时间) | 5-50米 | 高 |
| OrientationSensor | 高(持续) | ±2° | 中 |
| AccelerometerSensor | 高(持续) | ±0.01 m/s² | 中 |
使用建议:
- 不使用时关闭传感器(设 Enabled = false)
- 合理设置更新频率和间隔
- 对数据做平滑滤波减少噪声
- GPS定位在室外效果最佳
扫码添加客服咨询