11、Camera 特性检测:Characteristics查询、AvailableCapabilities枚举、HardwareLevel分级、Legacy/Limited/Full/Level3区别
做Android相机开发,有一件事你早晚得面对——设备碎片化。
我刚开始做相机App时,就踩过一个坑:明明在测试机上跑得好好的功能,换了一台千元机直接黑屏闪退。后来一查,人家那台设备根本不支持我调用的特性。从那以后,我养成了一个习惯:拿到CameraDevice之前,先查Characteristics。
说白了,CameraCharacteristics就是相机的“体检报告”。它告诉你这台设备能做什么、不能做什么、做到什么程度。今天我们就把它彻底讲透。
11.1 怎么拿到Characteristics?
获取方式很简单,但有个细节我提醒你注意——时机。
// 正确姿势:在打开相机之前查询
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
String cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
// 我习惯先查一下,再决定要不要打开相机
Integer level = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
if (level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
// 嗯,老设备,功能有限
}
这里有个坑:getCameraCharacteristics() 调用是同步的,但别在主线程里做太多查询。我一般只查一次,把结果缓存起来。
11.2 AvailableCapabilities:能力清单
这个枚举很有意思。它就像一张菜单,告诉你厨房里能做哪些菜。
| Capability 常量 | 含义 | 我遇到的坑 |
|---|---|---|
| MANUAL_SENSOR | 支持手动控制传感器(曝光、ISO等) | 有些设备标了支持,但实际调节范围很窄 |
| MANUAL_POST_PROCESSING | 支持手动后处理(色调、锐度等) | 这个和MANUAL_SENSOR经常成对出现 |
| RAW | 支持输出RAW格式 | 曾经以为有RAW就能做专业摄影,结果发现DNG元数据不全 |
| PRIVATE_REPROCESSING | 支持私有格式重处理 | 这个一般用在美颜、滤镜场景 |
| READ_SENSOR_SETTINGS | 支持读取传感器实时设置 | 很少设备支持,别依赖它 |
| BURST_CAPTURE | 支持连拍 | 连拍速度差异很大,有的每秒3帧,有的能到30帧 |
| CONSTRAINED_HIGH_SPEED_VIDEO | 支持高速视频(慢动作) | 需要配合SessionConfiguration使用 |
查询方式也很直接:
int[] caps = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
List<Integer> capList = new ArrayList<>();
for (int cap : caps) capList.add(cap);
if (capList.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
// 支持RAW,可以开启专业模式
}
我个人习惯把capabilities转成Set,这样查询效率高一些。你想想看,如果每次拍照前都遍历一遍数组,那多浪费。
11.3 HardwareLevel:硬件分级
这是Android相机框架里最核心的分级体系。它把设备分成四个等级,从低到高:
Legacy → Limited → Full → Level3
每个等级都包含前一个等级的所有能力,再加上一些新特性。
11.3.1 Legacy(传统级)
说白了,就是最基础的相机。没有手动控制,没有RAW,没有连拍。你想想看,2014年之前的手机基本都是这个级别。
- 只支持Camera1 API的等效功能
- 不支持YUV_420_888输出
- 不支持PRIVATE_REPROCESSING
- 我遇到过:有些低端平板,虽然Android版本很高,但相机还是Legacy
11.3.2 Limited(有限级)
这是目前市面上最常见的等级。比Legacy多了些东西,但还不够完整。
- 支持部分Capabilities(比如BURST_CAPTURE)
- 可能支持YUV输出,但不一定支持RAW
- 手动控制可能部分支持
- 我建议:如果你的App面向大众市场,以Limited为最低目标
11.3.3 Full(完整级)
到了这个级别,基本上该有的都有了。
- 支持所有Capabilities(除了Level3特有的)
- 支持30fps的YUV输出
- 支持手动控制传感器和后处理
- 支持RAW
- 支持连拍
我记得有一次做专业摄影App,要求最低支持Full级别。结果发现市面上大概只有60%的设备达标。嗯,这个比例你得心里有数。
11.3.4 Level3(三级)
这是Android 7.0引入的最高等级。它比Full多了什么?
- 支持YUV_REPROCESSING
- 支持输出到多个Surface(比如同时输出YUV和JPEG)
- 支持更精细的传感器控制
- 支持高分辨率的高速连拍
说实话,Level3的设备到现在也不算多。我做过统计,大概只有旗舰机才能达到这个等级。
11.4 四个等级的区别总结
| 特性 | Legacy | Limited | Full | Level3 |
|---|---|---|---|---|
| 手动曝光/ISO | ❌ | 部分 | ✅ | ✅ |
| RAW输出 | ❌ | 可能 | ✅ | ✅ |
| YUV_420_888 | ❌ | 可能 | ✅ | ✅ |
| 连拍 | ❌ | 可能 | ✅ | ✅ |
| YUV重处理 | ❌ | ❌ | ❌ | ✅ |
| 多Surface输出 | ❌ | 有限 | 有限 | ✅ |
我的建议:写代码时不要假设设备等级。每次都查一下,然后根据等级做功能降级。比如:Full以上才显示专业模式,Limited只显示基础拍照,Legacy就老老实实当傻瓜相机。
注意:有些设备会虚报等级。我曾经遇到过一台设备,HardwareLevel报的是Full,但实际连RAW都输出不了。所以,查完等级之后,最好再验证一下关键Capabilities。
11.5 实战:如何根据等级做功能适配
这里我分享一个我常用的适配策略:
private void setupCameraFeatures(CameraCharacteristics chars) {
Integer level = chars.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
int[] caps = chars.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
Set<Integer> capSet = new HashSet<>();
for (int c : caps) capSet.add(c);
// 1. 判断是否支持手动模式
boolean hasManual = (level >= CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
|| capSet.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR);
// 2. 判断是否支持RAW
boolean hasRaw = capSet.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW);
// 3. 判断是否支持连拍
boolean hasBurst = capSet.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE);
// 4. 判断是否支持高速视频
boolean hasHighSpeed = capSet.contains(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO);
// 根据这些标志位,动态显示UI控件
showManualControls(hasManual);
showRawOption(hasRaw);
enableBurstMode(hasBurst);
enableHighSpeedVideo(hasHighSpeed);
}
你看,这样写出来的代码,不管放到什么设备上都能自适应。我曾经把这个逻辑封装成一个工具类,后来好几个项目都直接复用,省了不少事。
11.6 一张图看懂整个体系
下面这张SVG图,把Camera特性检测的整个流程串起来了。从拿到Characteristics开始,到最终决定App能做什么,一目了然。
嗯,这张图把整个流程串起来了。你从CameraManager拿到Characteristics,然后查两个东西:HardwareLevel 和 Capabilities。前者告诉你设备属于哪个档次,后者告诉你具体支持哪些功能。两者结合,就能决定你的App能做什么、不能做什么。
最后说一句:别偷懒。每次打开相机前都查一遍,虽然多写几行代码,但能避免线上大量crash和功能异常。我见过太多App因为没做特性检测,在低端设备上直接闪退的案例了。
公众号:蓝海资料掘金营,微信deep3321