检测手机或平板的运动传感器:基于加速度计的水平仪、分步引导的轴向检查、指南针整圈扫描,以及在设备静止不动时进行的漂移测量。一切都在浏览器中完成。
正在等待第一个读数
把设备拿起来动一动。在一颗传感器真正报告出点什么之前,这里不会对它下任何结论:哪怕是一台连加速度计都没有的台式机,浏览器照样会提供同样的事件,只是把内容填成空值。
还没有加速度计读数
水平仪需要重力,而重力来自加速度计。动一动设备,或者检查上方是否已允许访问运动数据。
请在你想检测的那台设备上打开本页。台式机上这些传感器一个也没有,而任何浏览器都不会凭空造出它们。
手机的运动感知其实是三个各自独立、却装作一体的零件:一颗感知哪边朝下的芯片、一颗感知转动的芯片,还有一颗感知地磁场的芯片。它们各自会坏,坏法也各不相同,所以上面把它们分开来测。
加速度计测的是力,静止时这个力就是重力:手机正是靠它知道哪边朝上,单凭这一项就够用来做屏幕旋转和计步。陀螺仪测的是转动,是它带着镜头完成一次快速横摇、带着头显跟上一次转头,因为它在毫秒级就有反应,而重力要过一瞬才稳定下来。磁力计测的是地磁场,给另外两者一个可以依附的北。便宜的手机只装一颗加速度计;当游戏提示「不支持你的设备」时,缺的通常正是陀螺仪。
每一颗加速度计都有一个偏置——一个会加在测量值上的小常数——手机会减去出厂时标定的数值。一旦摔过,或者换过屏,传感器的参考系相对当初标定时的机身就偏了,这个校正也就不再对得上。结果就是:在一张绝对平整的桌面上,水平仪却读出一两度,而单次读数根本看不出来。把设备掉头转 180° 才能把两者分开,上面的检查做的正是这件事。
静止的陀螺仪会报出一个不为零的微小转动,凡是建立在它之上的东西都必须持续减掉这个数。只要这个数稳定,减法就管用,谁也察觉不到。一旦它变大——随年头、随温度、在一次磕碰之后——校正就跟不上了:游戏里的镜头自己往一边飘,手机静静躺着而指南针在转,头显里的世界在缓慢旋转。二十秒什么都不做,就足以把它测出来。
磁力计测量的是大约半高斯的磁场,而它周围几乎所有东西都更强:带磁扣的保护壳、车载支架、扬声器、笔记本的上盖、地板里的钢筋。看起来像指南针坏了的情况,大多只是干扰;地图应用让你画的那个「8」字,是手机在用一组新的方向重建自己的校正值。真正的故障是另一副模样:方位不是平滑滑动,而是跳变。上面的测试要求转满一圈而不是读一次,原因就在这里。
传感器装在主板上,而它们标定时所依据的参考系属于机身。换屏、换电池,或者一个被撬开又合上的机身,都可能让两者错位。水平仪忽然读不准、指南针要求反复校正、陀螺仪出现了以前没有的漂移——在一台刚被拆开过的设备上,这些值得一起检查。
运动数据可以用来推断别人在输入什么,也可以凭传感器各自独有的误差认出一台设备,所以 WebKit 不再白白交出这些数据:在 iPhone 和 iPad 上,网页必须在 https 下、由一次真实的点击发起请求。Android 上的 Chrome 不会询问——所以这个页面在一边有按钮、在另一边没有。无论哪种情况,读数都留在页面里:这里不会把任何东西发出去。