2026 年 6 月 16 日 · Android 17 稳定版推送 · API Level 37
这篇文章我们就一起来看看,针对相机相关内容,Android 17都有哪些更新吧。
Android 17 的相机更新可以分成下面两类:
| Google 能控制的 | updateOutputConfigurationsRAW14, CQ | |
| 需要厂商配合的 |
下面每一个更新点,都会标注这个属性,免得调了半天发现是设备不支持。
内容目录:
updateOutputConfigurations— 动态相机会话 Vendor-Defined Camera Extensions — 第三方 App 拍照丑的解法 RAW14 — 14bit RAW 终于有了统一格式 LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS — 多摄协同的细节 Eclipsa Video — Google 推的 HDR 视频标准 VVC / H.266 编码 常量质量(CQ)视频录制 Camera Device Type API 总结:哪些现在就能用,哪些还要等
一、updateOutputConfigurations — 动态相机会话
归属:Google 可控 ✅ | API Level 37 | 所有 Android 17 设备可用
以前,
相机 App 从拍照切到录像,传统做法是这样的:
// 旧时代的做法:cameraCaptureSession.close(); // 关掉cameraDevice.createCaptureSession( // 重新创建newConfigs, callback, handler);
这会导致:
画面黑一下(短则 100ms,长则 500ms+) 自动对焦、曝光全部重置,画面闪一下才稳定 如果你开了闪光灯准备拍,切模式那瞬间灯灭了又亮
手机厂的相机团队各自私下搞了黑科技绕过这个问题,但第三方 App 一直没办法。
Android 17 怎么解决的
// 假设你已经在跑一个 CameraCaptureSession// 想从 拍照模式 切到 录像模式:// 1. 准备好新的 OutputConfiguration 列表List<OutputConfiguration> videoOutputs = new ArrayList<>();videoOutputs.add(new OutputConfiguration(videoSurface)); // MediaCodec 的 SurfacevideoOutputs.add(new OutputConfiguration(previewSurface)); // 预览 Surface// 2. 直接更新——不关会话,不黑屏if (Build.VERSION.SDK_INT >= 37) {cameraCaptureSession.updateOutputConfigurations(videoOutputs);} else {// fallback 到老方法:close + recreateswitchToLegacyPath(videoOutputs);}
调完 updateOutputConfigurations 之后:
AE/AWB/AF 保持当前状态,不重置 预览不闪,不黑 不再需要提前把所有 Surface 都攥手里
值得注意的细节
updateOutputConfigurations 接受的 List 是全量替换,不是 diff。你传进去什么,会话里就留什么。所以你要自己保证预览 Surface 不被丢掉——除非你真的想切到"后台无预览"模式。
// ❌ 只传 videoSurface,预览会断session.updateOutputConfigurations(List.of(videoOutputConfig));// ✅ 预览和录像都要传session.updateOutputConfigurations(List.of(new OutputConfiguration(previewSurface),new OutputConfiguration(videoSurface)));
什么场景最实用
- 同时拍照+录像
:拍着视频发现精彩瞬间,截一张高分辨率照片 - 快速切换双摄流
:从主摄切到长焦时不用重建 session - 后台录制
:前台预览切走,但录制流保持
二、Vendor-Defined Camera Extensions — 第三方 App 拍照丑的解法
归属:厂商必须实现才有 ✅ | API Level 37 | 设备差异巨大
问题本质
你的手机拍张夜景照片,系统相机 App 走了这么一条链:
Sensor RAW → ISP → 多帧合成 → 降噪 → 色调映射 → 超分 → 出图而第三方 App(微信、Instagram)走的是:
Sensor RAW → ISP → 出图中间那一大堆计算摄影管线,Google 一直没有标准化的方式暴露给第三方。每个厂商都有自己的私货,但都不给外人用。
Android 17 的架构
之前 Android 也有 CameraExtensionCharacteristics,但只支持 Google 预定义的几种扩展类型:EXTENSION_HDR、EXTENSION_NIGHT、EXTENSION_BOKEH、EXTENSION_FACE_RETOUCH。
Android 17 加了个新东西:厂商可以自己定义扩展类型。
完整的调用链路:
// ========== 第一步:查询设备有什么扩展 ==========CameraManager manager = context.getSystemService(CameraManager.class);String cameraId = ”0”; // 通常是后置主摄CameraExtensionCharacteristics extChars =manager.getCameraExtensionCharacteristics(cameraId);// getSupportedExtensions() 现在返回的不仅是标准扩展// 还包含厂商自己注册的扩展 ID(比如小米的 ”SUPER_NIGHT”)ListallExtensions = extChars.getSupportedExtensions(); for (int ext : allExtensions) {boolean supported = extChars.isExtensionSupported(ext);Log.d(”CAM”, ”扩展 ID ” + ext + ” 是否支持: ” + supported);// 查这个扩展支持什么输出分辨率Listsizes = extChars.getExtensionSupportedSizes( ext, ImageFormat.JPEG);}// ========== 第二步:建立扩展会话 ==========ExtensionSessionConfiguration config =new ExtensionSessionConfiguration.Builder(CameraExtensionCharacteristics.EXTENSION_NIGHT, // 你要用的扩展类型outputConfigs,executor,new CameraExtensionSession.StateCallback() {@Overridepublic void onConfigured(@NonNull CameraExtensionSession session) {// 会话建好了,可以开始拍session.capture(request, callback, handler);}@Overridepublic void onConfigureFailed(@NonNull CameraExtensionSession session) {// 大部分时候是这个扩展在这个设备上不支持// fallback 到普通 CameraCaptureSession}}).build();cameraDevice.createExtensionSession(config);
一个坑
isExtensionSupported(int)在 API Level 37 才有。之前 Android 12–16 上虽然有 Extension API,但只能枚举整个列表,不能针对一个扩展 ID 直接问是否支持。
如果你要兼容旧设备:
public static boolean isExtAvailable(CameraExtensionCharacteristics c, int extId) {if (Build.VERSION.SDK_INT >= 37) {return c.isExtensionSupported(extId);}// 旧版本:假设 getSupportedExtensions 里有的就是支持的return c.getSupportedExtensions().contains(extId);}
2026 年夏天的实际情况
| 还不支持 |
公允地说:这个 API 的战略意义很大,但处在「基础设施已就位,生态还没长起来」的阶段。
三、RAW14 — 14bit RAW 终于有了统一格式
归属:Google 可控 ✅ | 需要传感器硬件支持 | API Level 37
背景
Android 之前支持的 RAW 格式:
RAW_SENSOR | |||
RAW10 | |||
RAW12 | |||
RAW14 | 14bit | API 37 | 和很多专业相机一致的位深 |
14bit 比 12bit 多 4 倍 的亮度等级(16,384 vs 4,096)。后期调色时差别肉眼可见——尤其是暗部提亮,12bit 容易出 banding,14bit 扛得住。
API 用法
// 在 ImageReader 里直接指定 RAW14ImageReader reader = ImageReader.newInstance(width, height,ImageFormat.RAW14, // ← 新常量maxImages);// 或者在 CameraRequest 里 target 这个 reader 的 SurfaceCaptureRequest.Builder builder =cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);builder.addTarget(reader.getSurface());// 回调里拿到的 Image,format 就是 RAW14reader.setOnImageAvailableListener(reader1 -> {Image image = reader1.acquireLatestImage();if (image.getFormat() == ImageFormat.RAW14) {// 处理 14bit RAW 数据ByteBuffer buffer = image.getPlanes()[0].getBuffer();// 每个像素 2 bytes(16bit 存储,低 14bit 有效)// 注意:buffer 是 packed 还是 unpacked,看传感器实现}image.close();}, handler);
彩蛋
RAW14 的 ImageFormat 常量值是 0x2026——Android 17 是 2026 年发布,Google 工程师埋的。
注意
RAW14 不等于"所有传感器都能输出 14bit"。如果传感器本身只有 12bit ADC,那 RAW14 只是高位补零。用下面这行确认传感器原生位深:
int[] bitsPerSample = characteristics.get(CameraCharacteristics.SENSOR_INFO_BITS_PER_SAMPLE);
四、LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS — 多摄协同的细节
归属:Google 可控 ✅ | API Level 37
场景
现在手机普遍是主摄 + 超广 + 长焦的逻辑多摄组合。你在 zoom 过程中从主摄切到长焦,系统内部两个摄像头会有一段"共存期"——主摄还没下班,长焦已经开始上班。
Android 17 之前:你只能拿到当前主输出的摄像头的 metadata。另一个摄像头虽然在跑,但你不知道它的曝光参数、帧率、对焦状态。
Android 17:通过新的 capture request key,可以拿到所有活跃物理相机的 metadata。
// 开启”额外物理相机结果”CaptureRequest.Builder builder =cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);builder.set(CaptureRequest.LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS,CaptureRequest.LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS_ON);// 在 CaptureCallback 里:CaptureCallback callback = new CaptureCallback() {@Overridepublic void onCaptureCompleted(CaptureRequest request, TotalCaptureResult result) {// 旧的 API——只有主输出的物理相机Map<String, CaptureResult> physicalResults =result.getPhysicalCameraResults();// Android 17 新的——所有活跃的物理相机if (Build.VERSION.SDK_INT >= 37) {Map<String, TotalCaptureResult> allPhysical =result.getPhysicalCameraTotalResults();for (Map.Entry<String, TotalCaptureResult> entry :allPhysical.entrySet()) {String physicalId = entry.getKey();TotalCaptureResult physicalResult = entry.getValue();// 可以读到每个物理相机的完整 metadataFloat focalLength = physicalResult.get(CaptureResult.LENS_FOCAL_LENGTH);// ...}}}};
谁用得上
- 相机 App 开发者
:zoom 条上显示"当前是哪个摄像头",不再靠猜 - 计算机视觉 App
:多摄同时取数据做深度估计或融合
五、Eclipsa Video — Google 推的 HDR 视频标准
归属:Google 可控 ✅ | 需要屏幕和编码器硬件支持
它到底是什么
Eclipsa Video 是 Google + Apple + NBCUniversal 联合推的一套 HDR 视频标准,基于 SMPTE ST 2094-50,开源无授权费。对标 Dolby Vision,但不要钱。
核心思路:视频里嵌入动态元数据,播放设备根据自己屏幕能力和环境光,实时决定怎么映射 HDR 内容。
拍 Eclipsa HDR 视频
// 1. 检查设备是否支持CameraCharacteristics chars =manager.getCameraCharacteristics(cameraId);int[] availableProfiles = chars.get(CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES);boolean eclipsaSupported = false;for (int profile : availableProfiles) {if (profile == DynamicRangeProfiles.HLG10_SMPTE_2094_50) {eclipsaSupported = true;break;}}if (!eclipsaSupported) {// 不支持 Eclipsa,fallback 到普通 HDR 或 SDRreturn;}// 2. 配置 CaptureRequest 使用 Eclipsa 动态范围CaptureRequest.Builder builder =cameraDevice.createCaptureRequest(TEMPLATE_RECORD);builder.set(CaptureRequest.DYNAMIC_RANGE_PROFILE,DynamicRangeProfiles.HLG10_SMPTE_2094_50);// 3. 创建 MediaCodec 编码器// 注意:不需要特殊配置,元数据会自动从 camera 管线透传到编码器MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_HEVC, width, height);format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);format.setInteger(MediaFormat.KEY_FRAME_RATE, fps);format.setInteger(MediaFormat.KEY_COLOR_FORMAT,MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);MediaCodec encoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_HEVC);encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);Surface encoderSurface = encoder.createInputSurface();// 把 encoder surface 加到 capture session 里// camera 输出 HDR 数据 → encoder → muxer
Google 文档里的原话
你不需要给 MediaCodec 设什么特殊的 HDR 参数。如果 active dynamic profile 包含 SMPTE 2094-50 元数据,framework 会自动把它传递下去。
你只要在 camera 端配好 profile,后续环节框架全包。这是这次做得比较干净的地方。
六、VVC / H.266 编码
归属:Google 可控 ✅ | 需要 SoC 硬件解码器
新的 MIME type:
MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_VVC, width, height);// ”video/vvc”
检查解码器:
MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);MediaCodecInfo codecInfo = codecList.findDecoderForFormat(MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_VVC, 1920, 1080));if (codecInfo != null) {// 可以硬解 VVC}
编码方面:目前几乎没有手机的硬件编码器支持 VVC。这是一个"先有解码,编码再等等"的状态——和当年 HEVC 的普及路径类似。
七、常量质量(CQ)视频录制
归属:Google 可控 ✅ | API Level 37
MediaRecorder recorder = new MediaRecorder();// ... 常规设置 ...// Android 17 新增if (Build.VERSION.SDK_INT >= 37) {recorder.setVideoEncodingQuality(MediaRecorder.VideoEncodingQuality.CQ);}
这个参数的意思是:"别给我限定码率,我需要多少比特你给我多少。简单画面少用,复杂画面多用。"
和 CBR(固定码率)的核心区别:
CBR: ████░░░░████░░░░████░░░░(所有场景都一样的比特预算)CQ: ██████████░░██████████░░(简单场景省下来的比特,给复杂场景用)
八、Camera Device Type API
归属:Google 可控 ✅ | API Level 37
int deviceType = cameraManager.getCameraDeviceType(cameraId);// 返回值含义switch (deviceType) {case CameraManager.CAMERA_DEVICE_TYPE_BUILT_IN:// 0 — 内置摄像头break;case CameraManager.CAMERA_DEVICE_TYPE_EXTERNAL_USB:// 1 — USB 外接摄像头break;case CameraManager.CAMERA_DEVICE_TYPE_VIRTUAL:// 2 — 虚拟摄像头break;}
场景:Zoom、Teams 这类视频会议 App 可以通过这个区分"笔记本的摄像头"和"外接的高清摄像头",给用户展示不同图标或默认选择。
九、总结:哪些现在就能用,哪些还要等
updateOutputConfigurations | close + create 即可 | |
RAW14 | ||
LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS | ||
| Vendor Extensions | 厂商实现后才有 |
Android 17 的相机更新里,最值得你现在就接的是 updateOutputConfigurations。它没有硬件依赖,不挑厂商,实实在在让你的 App 少黑屏几百毫秒。
至于 Vendor Extensions 这种,先了解一下 API,等手机厂的旗舰机下半年更新了再认真搞。
《更多交流,欢迎加入知识星球》
评论 (0)