2、SensorManager入门:获取系统服务、认识Sensor类

好,咱们正式开始玩加速度传感器。

上一章我们聊了传感器能干什么,这一章直接上手——怎么在代码里拿到传感器,怎么操作它。

说白了,Android 把传感器封装成了两个核心角色:SensorManagerSensor。一个管“怎么拿到传感器”,一个管“传感器本身是什么”。

2.1 获取 SensorManager:系统服务的正确打开方式

Android 里很多硬件功能都通过系统服务暴露给开发者。传感器也不例外。

获取 SensorManager 的代码,我猜你闭着眼都能写出来:

SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

嗯,就这么一行。

不过这里有个小细节——千万别在 onCreate 里反复调用 getSystemService。我个人习惯是在 Application 或 Activity 的成员变量里只获取一次,然后复用。为什么呢?

我曾经在一个项目里看到同事在 onResume 里每次都重新获取 SensorManager,结果内存里 SensorManager 对象被创建了好几次,虽然不会崩溃,但 GC 频繁触发,界面偶尔卡顿。你想想看,一个系统服务而已,全局单例的,没必要重复拿。

💡 我的建议: 在 Activity 的 onCreate 里获取一次,存成成员变量。或者用 Application 级别的 Context 获取,避免 Activity 泄漏。

2.2 Sensor 类:传感器的身份证

拿到 SensorManager 之后,下一步就是获取具体的传感器对象。

Sensor 类本身不复杂,它更像一个“描述者”——告诉你这个传感器叫什么、什么类型、量程多少、功耗如何。

获取加速度传感器的代码:

Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

如果返回 null,说明设备上没有加速度传感器。嗯,这种情况现在很少见了,但低端机或某些平板确实可能没有。

2.3 Sensor 的核心属性

拿到 Sensor 对象后,你可以看看它的“简历”。我个人经常用这几个属性:

方法 返回值 说明
getName() String 传感器名称,比如 "BMA250"
getType() int 传感器类型,加速度是 1 (Sensor.TYPE_ACCELEROMETER)
getMaximumRange() float 最大量程,单位 m/s²,常见 ±19.6 或 ±39.2
getResolution() float 分辨率,数值越小越灵敏
getPower() float 功耗,单位 mA,一般加速度传感器在 0.1~0.5 mA
getVendor() String 供应商,比如 "Bosch" 或 "STMicroelectronics"
getVersion() int 版本号,通常为 1

你可能会问:知道这些有什么用?

举个例子。我在做计步器的时候,发现某款手机的加速度传感器量程只有 ±19.6,而另一款是 ±39.2。前者在剧烈运动时数据会“削顶”,导致计步不准。所以,如果你做运动类 App,最好先读一下 getMaximumRange(),动态调整算法。

🔑 重点: Sensor 对象只是“描述信息”,它不负责采集数据。真正干活的是 SensorEventListener,我们下一章会讲。

2.4 获取所有传感器列表

有时候你不知道设备上到底有哪些传感器。可以用这个方法扫一遍:

List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
for (Sensor s : sensorList) {
    Log.d("Sensor", "name: " + s.getName() + ", type: " + s.getType());
}

我建议你在开发阶段把这个日志打开,看看真机上到底有哪些传感器。有一次我发现一台设备上居然有两个加速度传感器——一个主芯片内置的,一个外挂的。嗯,这种情况虽然少见,但遇到了你就知道怎么处理了。

2.5 知识体系图

下面这张图帮你理清 SensorManager 和 Sensor 的关系:

SensorManager 与 Sensor 关系图 SensorManager 系统服务,传感器总管 getDefaultSensor() Sensor 传感器描述信息 getSensorList() List<Sensor> 所有传感器列表 getName() getType() getMaximumRange() getPower() Sensor 只描述传感器属性,不采集数据

2.6 避坑指南

⚠️ 我曾经踩过的坑:
  • getDefaultSensor 可能返回 null——一定要判空,否则直接 NullPointerException 教你做人。
  • 不要在主线程做传感器注册/注销的耗时操作——虽然 getDefaultSensor 很快,但后续的监听回调是在单独线程跑的,如果你在回调里更新 UI,记得切回主线程。
  • 模拟器上传感器数据是模拟的——真机调试才是王道。我见过有人用模拟器调了三天,一上真机数据完全不对。

2.7 小结

这一章我们干了三件事:

  • 学会了怎么拿到 SensorManager
  • 认识了 Sensor 类,知道它能告诉我们什么
  • 了解了传感器的核心属性,以及怎么获取所有传感器列表

嗯,基础打牢了。下一章我们就要让传感器真正“动”起来——注册监听、接收数据。到时候你会发现,原来加速度传感器的数据长这样。


公众号:蓝海资料掘金营,微信deep3321