当发布Android 9(API 28)时,我很高兴发现带有多个摄像头的手机的物理摄像头会暴露出来,我为无法访问它们而感到非常沮丧。今天我偶然发现了Android Q documentation,上面写着:
从API级别29开始,某些或所有物理相机可能不会独立地暴露给应用程序,在这种情况下,CameraManager.getCameraIdList()中将不提供物理相机ID。但是应用程序仍然可以通过调用CameraManager.getCameraCharacteristics(String)来查询物理相机的特征。
此声明使我感到困惑,是否意味着Android正在回溯?变更的目的是什么?
我有兴趣在非常精细的水平上管理相机,这种变化是否会阻止我使用Android 9进行今天的工作?
它说可能不再列出ID,但是仍然可以查询其特征,我们应该如何在没有ID的情况下获取摄像机的特征?我猜我们应该通过逻辑相机上的getPhysicalCameraIds()
获取物理相机的ID,但这是否意味着如果我们想使用“隐藏”相机,就必须测试一堆随机ID字符串?
我们还能在未曝光的物理相机上使用SessionConfiguration创建捕获会话吗?
有人可以阐明这一点吗?
答案 0 :(得分:2)
我尝试使用 Pixel 5 (Android 11) 的第一个逻辑后置摄像头的物理 ID 打开摄像头,但失败并显示错误:未知摄像头 ID....
因此 Pixel 5 仅返回 2 个逻辑相机 ID,并且只能使用 cameraManager.openCamera(...)
方法打开这 2 个相机...
Samsung S10(也是 Android 11)返回 4 个逻辑摄像头 id,并且所有这些逻辑摄像头都没有任何物理摄像头 id,所有 4 个摄像头都可以毫无问题地使用。
Pixel 5 相机信息:
Samsung S10 相机信息:
虽然我没有尝试 Pixel 5 setPhysicalCameraId(cameraId)
https://developer.android.com/reference/android/hardware/camera2/params/OutputConfiguration.html#setPhysicalCameraId(java.lang.String)
我觉得这个方法可以用来切换不同的物理相机(比如我们可以打开广角相机)
更新
是的,我们可以在 Pixel 4、5(我猜还有更多设备和制造商)上使用 setPhysicalCameraId
方法来设置特定的物理相机
接下来是逻辑:
您使用相机管理器使用逻辑相机 ID 打开相机
那么如果该逻辑相机支持多相机功能,那么它应该具有非空的物理相机 ID 列表
您可以从物理相机 ID 列表中选择任何 ID 并将其设置为 OutputConfiguration
:
val outputs = surfaces.map {
OutputConfiguration(it).apply {
setPhysicalCameraId(cameraIdx)
}
}
cameraDevice.createCaptureSessionByOutputConfigurations(
outputs,
stateCallback,
backgroundCameraHandler
)
更新! WARNING! 但是它预览的是同一个视图,所以这个方法似乎不起作用(虽然没有例外),没有任何改变,无论你是否设置了物理相机
似乎从 Android 10 开始就坏了 - Android 10 (api 29) camera2 api regression with wide-angle camera
更新
我还尝试使用 SessionConfiguration
对象而不是不推荐使用的方法 createCaptureSessionByOutputConfigurations
来创建捕获会话
val config = SessionConfiguration(
SessionConfiguration.SESSION_REGULAR,
outputs,
backgroundCameraExecutor!!,
stateCallback
)
cameraDevice.createCaptureSession(config)
但仍然没有任何改变
答案 1 :(得分:1)
这不是回溯。实际上,这种概括是向您更好地控制复杂相机设置的重要步骤。
在API 29之前,如果制造商无法为构成复合相机的每个镜头提供单独的 cameraDevice ,则他们无法将镜头参数公开给开发者。他们唯一的选择是将复合相机整体曝光。
问题不是
我们还能在未曝光的物理相机上使用SessionConfiguration创建捕获会话吗?
但是,
现在我们可以读取之前无法曝光的物理相机的特征!
有了新的更改,制造商可以为您提供“后置摄像头1”,“后置摄像头2”等所有可用信息,即使没有办法在它们上开始单独的捕获会话。
在API级别29之前,保证所有返回的ID均由CameraManager.getCameraIdList()返回,并且可以由CameraManager.openCamera()直接打开。从API级别29开始,对于返回的每个ID,如果CameraManager.getCameraIdList()也返回了ID,则CameraManager.openCamera()可以将其用作独立的摄像头。否则,摄像机ID只能用作当前逻辑摄像机的一部分。
这意味着您可以使用getPhysicalCameraIds()在CameraManager.getCameraCharacteristics(id)中返回的任何ID:
从API级别29开始,此功能还可用于查询只能用作逻辑多机的一部分的物理机的功能。无法通过openCamera(String, CameraDevice.StateCallback, Handler)直接打开这些相机。