刚刚开始使用 Camera2 框架,因为它提供了对相机低级功能的更多控制。但是,我在快速打开和关闭手电筒时遇到了一些麻烦。使用旧的 Camera API,我可以通过以下方式在提供预览的同时切换闪光灯:
try
{
android.hardware.Camera.Parameters parameters = c.getParameters();
if (parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_OFF))
{
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
Log.i("HeartBeatAlgorithm", "LightOn");
}
else if (parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_TORCH))
{
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
Log.i("HeartBeatAlgorithm", "LightOff");
}
c.setParameters(parameters);
}
catch (Exception exception)
{
c.release();
c = null;
}
手电筒会快速打开或关闭,没有任何明显的中断。然而,对于 Camera2,似乎 flash 模式是 CaptureSession 的一个属性,这意味着需要创建一个全新的 CaptureSession 来更改 flash 模式,即:
try
{
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface surface = new Surface(texture);
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
if (mLightNowOn == true)
{
mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
}
else
{
mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
}
mPreviewRequestBuilder.addTarget(surface);
mPreviewRequest = mPreviewRequestBuilder.build();
mCameraDevice.createCaptureSession(Arrays.asList(surface), mSessionStateCallback, null);
}
catch (CameraAccessException e)
{
e.printStackTrace();
}
正如开发者文档中提到的,“创建会话是一项昂贵的操作,可能需要数百毫秒,因为它需要配置相机设备的内部管道并分配内存缓冲区以将图像发送到所需的目标。” 确实如此,并且在切换 Flash 模式时,我的应用程序有明显的延迟。
我真的需要能够快速切换闪光模式而不会过多地中断预览。有什么办法可以解决这个问题,还是由于新的 API 管道而不可避免?