Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。
文章代表作者个人观点,少数派仅对标题和排版略作修改。
睡觉是每一个人与生俱来的技能,但却没人能十分自信地说了解自己的睡眠状况,所以我们需要比较专业的手段来进行睡眠监测。
本文就以从业者的角度出发,和大家聊聊移动端睡眠监测的相关原理、技术和应用。
顾名思义,便是通过采集人类在睡眠期间的生理数据来监测分析其睡眠质量的过程。当然,这是我非常朴素的理解,在医学上,睡眠监测其实还是一个不小的研究领域,且普通人并不是研究对象,而是有相关障碍的患者。从为数不多的 百科资料 中我们可以了解到最常见的诊断方法:
多导睡眠图监测(Polysomnography,PSG)又称睡眠多项生理检查,是睡眠医学、睡眠障碍、打鼾、癫痫、睡眠呼吸中止症等相关睡眠疾病当中,最常被安排进行的标准生理诊断方法。多项生理检查顾名思义,需要透过多种仪器的配合,方能进行检查的综合诊断方法。
PSG的检查内容一般包括睡眠情况(脑波图、眼动图、肌电图)、呼吸情况(血氧、胸腹动作、口鼻气流)、心脏情况等,受检者身上会安装多种仪器的侦测电极。目前很多医院也有专门的睡眠中心提供相关检查项目。
需要留宿于医院一个晚上,做为期6-8小时的睡眠记录,而且需要全程配有专业睡眠检查的人员或医生。因此如果对于自己的睡眠有所疑问,可以洽询耳鼻喉科、胸腔内科、精神病学的医生以及睡眠技师(呼吸治疗师)等。
睡眠监测有何用处呢?
医学上的监测手段往往需要对应的专业器具,过程较为复杂,但却为移动设备上的简化版监测提供了理论基础,后者又在一定程度上普及了睡眠监测,降低了的使用者的成本。即便我们不是相关病症的患者,也有了更便捷的方式来了解自己的睡眠状况,以便预防,即时就医。
市面上也有很多商家专门贩卖睡眠监测仪之类的消费级设备(某些有点智商税的感觉),相比医院的医疗级设备肯定是差了不少,个人认为借助移动端的睡眠监测来知晓简况就已经足够。
目前很多手机厂商利用自己软硬结合的研发优势,开始进军健康应用领域。比如 Apple、华为、小米等国内外厂商都内置了独立的健康 App。睡眠监测都还只是这些 App 的主要功能之一,除此之外还有运动、体重、心率、生理周期等相关功能,结合各家自己的穿戴设备,产品形态可以说是比较丰富了。
Apple 在健康 App 的开发上面应该是起步最早的,产品功能都已经非常成熟了。在早期的 iOS 13 及以前版本,健康和时钟 App 就有联动的功能,在时钟上使用「就寝」,可以追踪用户的睡眠时长。
只需设置希望的每夜睡眠时长,「时钟」应用便可提醒您就寝,并通过播放闹钟来唤醒您。
在 iOS 14 以后,Apple 将睡眠相关的功能深度整合到了健康 App 中,比如设置睡眠目标、编辑睡眠定时等。结合 Watch,可以进一步追踪各项睡眠指标,如血氧、心率、呼吸频率等。关键的睡眠数据还是通过穿戴设备的传感器来采集,同步到手机之后再做数据分析与展示。
早期的 Watch 其实就已经内置了检测血氧的光学传感器,但并没有提前开放,因为之前很多消费级的穿戴设备所推出的血氧检测功能并未获得相关的医疗认证,准确性和可靠性都存疑。如今上线这项指标想必也是经过了较为成熟的验证。
Apple 在睡眠这个功能集合上,相比其他产品,没有特别复杂的数据分析报告(至少在交互层面不是那么的花里胡哨),不给用户太大的压力,更多的是关注用户睡没睡着,睡了多久。睡眠监测固然是核心业务逻辑,但产品策略上,睡眠目标、睡前助眠、叫醒起床也是同样重要,给了用户一套比较完整的体验。
总而言之,数据过于丰富有时候并非是一件好事,只有得到充分研究论证后,那些确实跟睡眠状况有相关性的数据才有价值展示给用户。
小米在 MIUI 12 推出的时候,也着重介绍了其内置的健康 App,现在 MIUI 12.5 的官网依然有健康的介绍入口。从初版的体验来看,功能也算是比较齐全了,看得出来内部团队在这个产品孵化上花的时间不少。
从最新官方海报来看,睡眠并没有作为重点功能介绍,但其依然是小米健康 App 的主要功能模块之一,除此之外,还有运动、心率、经期、健身课程等模块。这里的心率是一个单独的模块,并没有作为睡眠监测的依赖数据。
小米健康的睡眠模块基本与 Apple 的睡眠类似,比较有特色的是深浅睡和鼾声梦话记录,可以回放自己的梦话音频。作为系统应用,不管是交互还是功能本身,从我的实际使用体验来看,要优于国内大多数同类竞品,小米的产品定位或多或少有一些可玩性。
国内很多厂商都在学习 Apple 的产研路线,小米健康同样支持穿戴设备的数据互通,甚至在很早之前就提供了小米健康云开放平台用户文档,期望统一管理用户的健康数据,避免生态链企业各搞各的。
与 Apple 不同的是,小米健康不仅会利用穿戴设备同步过来的数据,还醉心于挖掘手机本体的监测能力。比如上面海报提到的运动算法,基于加速度传感器;睡眠模块的深浅睡,也是基于加速度传感器,并结合亮屏时间来分析;鼾声梦话,基于麦克风等录音器件。即便你没有购买手表等设备,也可以体验睡眠监测功能。
其实华为在运动健康 App 的研发上比小米等国内厂商要先行一步,内部也有单独的大健康部门,在穿戴设备方面的布局也比较早。与 Apple、小米不同的是,华为运动健康并非仅能安装在华为设备上,你甚至可以在小米应用商店下载它。
除了睡眠监测分析等基本功能外,锦上添花的配套服务也比较丰富,例如白噪音、冥想等,属实是抢了不少三方应用的用户。
由于个人近几年对华为产品体验比较少,此处就点到为止了。
仍然需要重点说明的是,手机厂商有一个很大的优势便是硬件,尤其是在传感器数据采集、穿戴设备的生态建设等方面,定制化地的集成研发都比三方应用只在数据层玩得开。
虽然手机厂商在硬件层面有更好的专属集成和功耗控制,但睡眠监测从理论上需要的大部分数据在上层应用也能获取到,所以三方开发者也并不是毫无机会施展拳脚。当然,在耗电方面,大家睡觉的时候基本都是让手机保持充电状态,倒是不用考虑功耗问题,但户外运动相关的健康功能,三方应用相比系统应用就没有什么优势了。
此外,随着厂商平台生态的开放,以及健康数据相关API的系统级别沉淀与下放,三方应用的相对劣势会逐渐减少。尤其是近几年人工智能热潮再度掀起,机器学习在移动端的发展也逐渐成熟,Google 和 Apple 都在相关领域有所铺垫。
市面上有很多成熟的睡眠类 App,聊聊我最近发现的 Sleep as Android 这款应用,从应用配置清单(manifest)来看,就很可能利用了 Google 最新开放的 Sleep API,再结合自己的机器学习模型来实现睡眠监测。其功能丰富程度可以说是睡眠类应用的标准模板了。
在我体验几天下来,感觉监测还是比较准的,主要是在睡眠时间这一块,个人主观感受比以前用的初版小米健康要稍微准一点(主要是在入眠时间的判断上面)。就是 UI 风格实在是太 Material Design了,交互上反倒是稍微有点不适应。
深浅睡和快速眼动(REM)这些基本数据都会有。入睡前有催眠曲,叫醒时会使用闹钟提醒起床,并且必须通过某些小测验才能解锁并停止闹钟,以证明你真的清醒了。当然,这对那些梦里都能操作的人来说,或许……没什么用。
下面就是重点了,我们从软件到硬件层面聊一下睡眠监测的技术实现方式和原理。
不管是系统应用还是三方应用,其实应用软件本身在原始数据采集这一步能做的事情并不是很多,重点还是在数据的二次加工及使用上。比如 Apple 和国内 Android 厂商的系统级健康 App,其数据采集方式都是差不多的。
在手机设备上,它们无非是通过加速度传感器、光学传感器、扬声器/麦克风等元器件记录设备整晚的位移变化、光强度变化、声音变化信息,这些数据有分散也有连贯的。一些较为特殊的指标比如心率、血氧等,就依赖手表等穿戴设备来获取。
简单地讲,加速度传感器的数据源是最为重要的,它往往作为睡眠类 App 的主要训练分析对象,其他数据源作为辅助优化训练结果。我之前在使用小米健康的时候,它就会请求身体运动信息等类似权限,并告诉你尽量放在枕边,保证你自己和手机睡在同一张床上,以此来监测你入眠后翻身、扭头等动作带来的振动,作为深浅睡的识别依据。
例如,对 Android 应用开发者来说,监听部分传感器的数据实现起来也非常简单,系统底层框架已经屏蔽了不同手机设备的硬件差异。
private SensorManager sensorManager;
private Sensor sensor;
// 直接使用Android SDK提供的系统服务即可
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// 数据将以周期性事件的形式回调给开发者,加速度传感器是很多其他传感器的基础
public void onSensorChanged(SensorEvent event){
// In this example, alpha is calculated as t / (t + dT),
// where t is the low-pass filter's time-constant and
// dT is the event delivery rate.
final float alpha = 0.8;
// Isolate the force of gravity with the low-pass filter.
gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
// Remove the gravity contribution with the high-pass filter.
linear_acceleration[0] = event.values[0] - gravity[0];
linear_acceleration[1] = event.values[1] - gravity[1];
linear_acceleration[2] = event.values[2] - gravity[2];
}
当你把手机放在床头柜而不是床上时,发现最终识别效果并不是很理想,就说明此应用没有使用其他传感器的数据来辅助分析。
在鼾声、梦话和呼吸频率的监测中,麦克风等声学元器件就起到了至关重要的作用。深夜的卧室里,环境一般都很安静,背景噪音是非常少的,所以声音数据的采集就比较有用处了。但考虑到功耗和存储限制,App 一般不会整晚录音,那样生成的文件太大,也不便于分析,而是对分贝进行测量,大于设定阈值才会写入文件。
Sleep as Android 的简介中提到了用声纳原理来监测身体在呼吸时的起伏,这样就可以避免使用加速度传感器。类似的原理在渔业和军事上早已广泛运用,很多定位设备都会通过发射声波信号和接收反射信号来判断目标位移。
在我曾参与过的睡眠功能的开发中,并没有使用这个方法,当时主要是考虑到不同用户的睡眠环境、个体差异太大,且对设备的摆放位置要求较高,最终会导致训练难度加大。由于 Sleep as Android 并非开源软件,因此它这个声纳运用的有效性不太好验证。
上面讲到的方案是开发者自己采集传感器的原始数据来进行睡眠分析,但随着这一需求的增多和相关训练模型的成熟,Google 开始把睡眠监测整合成 API 加入到 GMS(谷歌移动服务)的服务框架中。
这些 API 相当于对各种传感器原始数据采集的方法做了二次封装,并且还内置了监测识别的模型,开发者无需再关心睡眠监测应该如何去采集数据、如何去训练了。Google 现在帮你做好了,你只需要调用 API,简单地处理结果事件即可。
从Sleep API官方文档来看,使用方式非常简单:
To get started, do the following:
- Target Android 10 (API level 29) or higher.
- Request the
ACTIVITY_RECOGNITION
permission.- Register for updates to the user's sleep behavior, including sleep segments and sleep event classification results, by calling
requestSleepSegmentUpdates()
.
只要设备基于 Android 10 及以上,声明并请求行为识别专属权限,再调用相应的方法即可获取睡眠事件,这些事件都是 GMS 在框架中已经识别分析之后的结果,开发者只需要关心自己的产品业务逻辑即可。
其中最重要且仅有的两个睡眠事件有必要介绍一下:SleepSegmentEvent 和 SleepClassifyEvent 。
SleepSegmentEvent 顾名思义就是睡眠片段事件,其中包含了用户每一段睡眠的关键信息:
关键方法 | 说明 |
---|---|
getEndTimeMillis() | 系统检测到用户停止睡眠并苏醒的时间 |
getSegmentDurationMillis() | 用户这段睡眠的持续时间(原文档特别提示到based on the device sensor data) |
getStartTimeMillis() | 用户开始入睡的时间 |
getStatus() | 事件状态,有数据缺失、无法检测和成功三种,第一种一般是数据采集不足导致的,第二种是识别结果置信度不够导致 |
而 SleepClassifyEvent,便是睡眠识别分类事件,包含了睡眠识别的置信度和传感器数据等信息,且此事件回调周期是固定间隔10分钟:
关键方法 | 说明 |
---|---|
getConfidence() | 0到100,值越大置信度越高,说明用户当前越可能处于睡眠状态 |
getLight() | 顺便返回环境亮度值 |
getMotion() | 顺便返回设备位移值,即加速度传感器的包装数据 |
getTimestampMillis() | 事件发生时的时间戳,是一个时刻,非连时间段 |
有了这些方法,睡眠类 App 开发的门槛大幅降低,大概是一件好事吧。当然,这就相当于完全信任 Google 的模型,且依赖 GMS 框架,国内恐怕不好普及。
不过之前在做竞品调研的时候,Pixel 机型的效果确实比其他手机好。同样的一份测试代码,在调用相关 API 时得到的事件数据更多、更连贯,这样更利于后续的处理和展示,而非寥寥几个事件,或者甚至没有;国产某些旗舰机(自带 GMS 框架)虽然也有效果,但比起亲儿子手机,还是要差一些。个人认为导致这个差距的主要原因,还是跟系统后台限制和底层框架的修改有关。
由于 GMS 的闭源特性,成熟的商业 App 肯定不会只使用 Google 的 Sleep API,更多是以此来辅助自己的算法,用户体验到的会是优化后的融合效果。例如我们前面提到的 Sleep as Android,设置选项中就有是否使用 Google 睡眠 API 的选项(默认打开),说明当你关闭的时候,它有自己的备选方案来兜底。
相比三方应用开发者,手机厂商的巨大优势就是硬件,这里说的硬件不仅仅是区别于手机的穿戴设备那么简单,而是指手机、手表等设备内部的芯片、传感器。
上层软件开发者在睡眠监测这个功能上有两个主要劣势:
针对上述 2 个缺点,对应聊一聊厂商的系统应用是如何解决的。
任何某个单一传感器都是无法满足监测识别任务的,厂商可以开发专属的传感器,来采集其他基本传感器的数据,融合成新的传感器事件(event)。这个专属传感器可以是真实元件,成本较高;也可是模拟的,一般在系统的硬件抽象层(HAL)做模拟。
最后对于上层的系统应用(System Apps)来说,就是多了一个可以监听的 Sensor 类型而已。
融合传感器可以避免上层应用同时监听多个传感器,大大降低功耗。很多人可能会有疑问:融合的数据不也是在底层同时采集了多个其他传感器吗?
确实是,但是它减少了从底层到上层一系列的框架调用,底层硬件的耗电其实远小于软件层面的CPU消耗电量。
有了融合传感器之后,我们可以进一步把一些较为固定的业务逻辑和算法模型下沉到系统底层,让专用的处理单元(比如 DSP、TPU 等)去做计算工作,最后直接把识别的结果传递给上层应用即可,传递数据之前的整个过程中都不需要唤醒上层的应用进程,应用层只需要在接收结果后稍作修饰,再做纯业务展示即可。
这一系列做法可以极大地降低设备功耗。这就是为什么某些厂商可以自信地宣称系统内置运动健康类App的各种活动识别全天耗电在 1% 以内。
睡眠监测越来越得到各家健康 App 的重视,虽然三方和厂商在基础能力上有先天差距,但随着技术的成熟,厂商为了建立自己的生态,也愿意开放能力出来给大家使用。降低行业总体成本的同时,未来角逐的更多还是产品体验。
> 下载 少数派 2.0 客户端、关注 少数派公众号,解锁全新阅读体验📰
> 实用、好用的 正版软件,少数派为你呈现🚀
© 本文著作权归作者所有,并授权少数派独家使用,未经少数派许可,不得转载使用。