4、SensorManager入门:获取SensorManager服务、获取默认光线传感器、传感器列表遍历
好,咱们正式开始写代码了。前面聊了那么多光线传感器的原理,现在终于要跟Android系统打交道了。这一节,我带你搞定SensorManager——它是所有传感器操作的入口。
4.1 什么是SensorManager?
说白了,SensorManager就是Android系统里管理传感器的一个管家。你想用光线传感器、加速度计、陀螺仪……都得先找它要。它负责三件事:
- 获取传感器实例——比如你要的光线传感器
- 注册/注销监听器——告诉系统什么时候通知你数据变化
- 提供传感器列表——看看设备上到底有哪些传感器可用
我个人习惯把SensorManager理解成“传感器中介”。你不直接跟硬件打交道,而是通过它来沟通。这样做的好处是,Android帮你处理了底层驱动的差异,你写一套代码,跑在不同手机上都能工作。
核心要点:SensorManager是一个系统服务,通过getSystemService()获取。每个Android应用只有一个实例,别重复创建。
4.2 获取SensorManager服务
怎么拿到这个管家?代码很简单:
// 在Activity或Service中
SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
嗯,就这一行。但这里有个坑——千万别在onCreate()里获取了就不管了。我记得有一次项目上线后,用户反馈说“手机发烫”,查了半天发现是SensorManager没在onPause()里释放资源。你想想看,传感器一直开着,CPU没法休眠,不烫才怪。
避坑指南:我曾经在Fragment里直接getActivity().getSystemService(),结果Fragment detached后还持有Activity引用,导致内存泄漏。建议在Application或ViewModel中获取,或者严格遵循生命周期。
4.3 获取默认光线传感器
拿到SensorManager后,下一步就是获取光线传感器实例。Android提供了两种方式:
4.3.1 获取默认传感器
Sensor lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
这个方法返回系统推荐的“默认”光线传感器。大多数手机上只有一个光线传感器,所以返回的就是它。但如果设备有多个同类型传感器(比如有些高端机有前置和后置光线传感器),这个方法只返回第一个。
4.3.2 获取指定类型的传感器列表
List<Sensor> lightSensors = sensorManager.getSensorList(Sensor.TYPE_LIGHT);
这个方法会返回所有光线传感器。你可以遍历这个列表,看看每个传感器的厂商、版本、最大量程等信息。
我的建议:日常开发用getDefaultSensor()就够了。除非你要做特殊处理,比如判断前置光线传感器和后置光线传感器的差异,才需要用getSensorList()。
4.4 传感器列表遍历
有时候你想看看设备上到底有哪些传感器。比如调试时确认光线传感器是否存在,或者想了解传感器的具体参数。这时候遍历传感器列表就很有用了。
// 获取所有传感器
List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
for (Sensor sensor : sensorList) {
Log.d("SensorInfo", "名称: " + sensor.getName());
Log.d("SensorInfo", "类型: " + sensor.getType());
Log.d("SensorInfo", "厂商: " + sensor.getVendor());
Log.d("SensorInfo", "版本: " + sensor.getVersion());
Log.d("SensorInfo", "最大量程: " + sensor.getMaximumRange());
Log.d("SensorInfo", "分辨率: " + sensor.getResolution());
Log.d("SensorInfo", "功耗: " + sensor.getPower() + " mA");
Log.d("SensorInfo", "---");
}
这段代码会打印出设备上所有传感器的信息。我经常在项目初期跑一遍这个,看看目标设备支持哪些传感器。有一次客户说“我们的平板有光线传感器”,结果我一跑代码,列表里根本没有TYPE_LIGHT——嗯,硬件支持但驱动没配好,这种坑我也踩过。
4.5 知识体系总览
下面这张图帮你理清SensorManager的核心逻辑:
4.6 完整示例代码
把上面几块拼起来,就是一个完整的入门示例:
public class LightSensorActivity extends AppCompatActivity {
private SensorManager sensorManager;
private Sensor lightSensor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_light_sensor);
// 1. 获取SensorManager服务
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
// 2. 获取默认光线传感器
lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
if (lightSensor == null) {
// 设备不支持光线传感器
Log.w("LightSensor", "当前设备没有光线传感器");
return;
}
// 3. 打印传感器信息
Log.d("LightSensor", "传感器名称: " + lightSensor.getName());
Log.d("LightSensor", "最大量程: " + lightSensor.getMaximumRange() + " lux");
Log.d("LightSensor", "分辨率: " + lightSensor.getResolution() + " lux");
Log.d("LightSensor", "功耗: " + lightSensor.getPower() + " mA");
// 4. 遍历所有传感器(可选)
List<Sensor> allSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
for (Sensor sensor : allSensors) {
Log.d("SensorList", "类型: " + sensor.getType() + " | 名称: " + sensor.getName());
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 记得清理,避免内存泄漏
// 后面章节会讲registerListener和unregisterListener
}
}
关键检查点:获取光线传感器后,一定要判断是否为null。很多低端设备或特殊设备(比如某些电视盒子)根本没有光线传感器。不做判断直接使用,会抛出NullPointerException。
4.7 常见问题
| 问题 | 原因 | 解决方法 |
|---|---|---|
| getDefaultSensor()返回null | 设备没有该类型传感器 | 检查设备硬件,或做降级处理 |
| 传感器列表为空 | 权限问题或模拟器不支持 | 真机调试,检查AndroidManifest |
| 获取到多个同类型传感器 | 设备有多个物理传感器 | 根据厂商或版本选择需要的那个 |
好了,SensorManager的入门就这些。说白了就是三步:拿服务、取传感器、用传感器。下一节我们会真正让光线传感器“动起来”——注册监听器,实时读取光照数据。
公众号:蓝海资料掘金营,微信deep3321