MozStumbler为什么静止就暂停扫描?运动检测双传感器省电算法详解
【免费下载链接】MozStumblerAndroid Stumbler for Mozilla项目地址: https://gitcode.com/gh_mirrors/mo/MozStumbler
MozStumbler 是 Mozilla 出品的 Android 众包地理数据采集应用,它通过扫描周围的 Wi-Fi 热点、蜂窝基站并上传位置报告,持续完善 Mozilla 位置服务(MLS)的数据库。为了让手机能 7×24 小时挂着扫描而不把电池耗光,MozStumbler 设计了一套「运动检测双传感器」省电算法:人不动就暂停扫描,一挪窝立刻唤醒💡。这篇文章用大白话讲透它的判定逻辑、唤醒机制和防误报细节。
一、问题背景:扫描为什么耗电?
先理解 MozStumbler 的工作方式。它的扫描核心由 ScanManager.java 管理,同时驱动 4 个采集器:
- GPS 扫描器:持续定位,是数据报告的"坐标锚点"
- Wi-Fi 扫描器:枚举可见热点
- 蜂窝基站扫描器:读取信号强度
- 气压扫描器:辅助楼层判断
这 4 个硬件(射频 + 卫星)同时工作,是典型的耗电大户。而现实中用户大量时间其实是静止的——通勤地铁上、上班办公、睡觉。静止时扫到的数据毫无价值,却一样烧电池。于是 MozStumbler 引入了一个状态机,扫描器可以在三种状态间流转:
| 状态 | 含义 | 耗电 |
|---|---|---|
STOPPED | 完全停止 | ⭐ |
STARTED | 正常扫描 | ⭐⭐⭐⭐ |
STARTED_BUT_PAUSED_MOTIONLESS | 已启动但因静止暂停 | ⭐⭐ |
这套状态机的关键定义就在 ScanManager.java 的ScannerState枚举中。
二、传感器一:LocationChangeSensor 判定"人静止了"
谁来宣布"用户不动了"?是LocationChangeSensor。它是一个广播接收器,监听 GPS 更新事件,逻辑非常简洁,见 LocationChangeSensor.java:
- 收到新 GPS 点时,判断是否在时间窗口 T 内移动了超过 D 米;
- 同时挂一个定时器,如果 T 秒内根本等不到有效的移动量,也判定为静止。
也就是说它用距离阈值 D + 时间窗口 T两个参数联合判定(这两个参数在开发者选项里可以调,对应 fragment_developer_options.xml 的两个下拉框)。一旦判定静止,就发出ACTION_LOCATION_NOT_CHANGING广播。
收到广播后,ScanManager 会执行pauseScanning(),把 4 个扫描器全部停掉,转入"静止暂停"状态:
[正常扫描 STARTED] │ D 米内未移动 & 超过 T 秒 ▼ [静止暂停 PAUSED_MOTIONLESS] ← WiFi/基站/GPS 全部休眠 │ 检测到明显运动 ▼ [恢复正常扫描 STARTED]注意一个巧妙的默认假设(源码注释原话):扫描启动时默认用户是"在移动"的,只有LocationChangeSensor明确说"不动了"才暂停。这保证了首次启动不会漏扫。
三、传感器二:MotionSensor 负责"把人唤醒"
暂停之后,谁来感知用户重新走动?答案是 MotionSensor.java,它按设备能力自动选择两种实现之一:
3.1 首选:SignificantMotionSensor(硬件触发器)
在 Android 4.3+ 且硬件支持的设备上,它注册TYPE_SIGNIFICANT_MOTION传感器,见 SignificantMotionSensor.java。
这是系统级的"显著运动"触发器——由芯片低功耗协处理器判定"你在走路/坐车了",然后才唤醒应用。平时几乎零耗电,是省电方案里最关键的一块拼图。
3.2 兜底:LegacyMotionSensor(加速度
【免费下载链接】MozStumblerAndroid Stumbler for Mozilla项目地址: https://gitcode.com/gh_mirrors/mo/MozStumbler
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考