我有2个AF对焦距离,可以通过按钮和一个用于闪光灯的On Off开关进行控制。
为什么updatePreview()中的flashligh的IF ELSE会影响自动对焦模式?当我注释掉该部分(如果为flashligh为IF ELSE)时,自动对焦模式和对焦距离可与btnFocus正常工作。
如何解决此问题同时仍可以允许用户打开和关闭手电筒?
private float focusDistance = 0;
private int flashSwitch = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textureView = (TextureView)findViewById(R.id.textureView);
//From Java 1.4 , you can use keyword 'assert' to check expression true or false
assert textureView != null;
textureView.setSurfaceTextureListener(textureListener);
btnFocus = (Button)findViewById(R.id.btnFocus);
btnFlash = (Button)findViewById(R.id.btnFlash);
btnFocus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
changeFocus();
}
});
btnFlash.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
Flash();
}
});
}
private void Flash() {
if(cameraDevice == null)
return;
if(flashSwitch == 0 ) {
Toast.makeText(MainActivity.this, "Flash Turn On ", Toast.LENGTH_SHORT).show();
flashSwitch = 1;
}
else{
Toast.makeText(MainActivity.this, "Flash Turn Off ", Toast.LENGTH_SHORT).show();
flashSwitch = 0;
}
createCameraPreview();
}
private void changeFocus() {
if(cameraDevice == null)
return;
if(focusDistance == 0 )
focusDistance = 10;
else
focusDistance = 0;
Toast.makeText(MainActivity.this, "Focus Change "+ focusDistance, Toast.LENGTH_SHORT).show();
createCameraPreview();
}
private void createCameraPreview() {
try{
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(),imageDimension.getHeight());
Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
if(cameraDevice == null)
return;
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(MainActivity.this, "Changed", Toast.LENGTH_SHORT).show();
}
},null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
如果您取消注释,打开闪光灯并更改焦点时将出现问题。
private void updatePreview() {
if(cameraDevice == null)
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
try{
// if you uncomment this part the problem will come out
// if(flashSwitch == 0){
// captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
// }
// else{
// captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
// }
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_OFF);
captureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, focusDistance);
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(),null,mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
可以在不影响对焦模式的情况下手动打开和关闭闪光灯。
答案 0 :(得分:0)
在updatePreview()
中,您要向cameraCaptureSessions
发送多个捕获请求,然后再设置captureRequestBuilder
中的所有键。首先尝试设置所有键,然后发送一个重复的捕获请求。
private void updatePreview() {
if(cameraDevice == null)
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
try{
if(flashSwitch == 0){
captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
}
else{
captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
}
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_OFF);
captureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, focusDistance);
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(),null,mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
答案 1 :(得分:0)
我认为您的问题可能出在设置请求的方式上。
您应该首先创建预览,并且只能按照自己的方式创建一次,每次切换闪光灯和/或对焦时都将创建预览。
我建议在onStart
中创建预览,并使用以下默认设置:
focusDistance = 0;
flashSwitch = CaptureRequest.FLASH_MODE_OFF;
然后在Flash()和changeFocus()
中,而不是通过调用createCameraPreview()
来调用updatePreview()
,更新预览将如下所示:
private void updatePreview() {
if(cameraDevice == null)
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
try{
captureRequestBuilder.set(CaptureRequest.FLASH_MODE, flashSwitch);
captureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, focusDistance);
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(),null,mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}