CameraSource .setAutoFocusEnabled(true) returns:尽管设备支持自动对焦,但此设备不支持相机自动对焦
CameraSource .setAutoFocusEnabled(true) returns: Camera auto focus is not supported on this device although device supports auto focus
下面是我的条形码扫描仪activity,除了setAutoFocusEnabled(true) 之外,一切正常。它 returns 一条运行时消息说我的设备不支持自动对焦,尽管 Samsung Tab E T561 是支持自动对焦的设备。
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.SparseArray;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.EditText;
import com.google.android.gms.vision.CameraSource;
import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.io.IOException;
import static com.google.android.gms.vision.CameraSource.CAMERA_FACING_BACK;
import static com.google.android.gms.vision.CameraSource.CAMERA_FACING_FRONT;
public class ScanBarcodeActivity extends AppCompatActivity {
private String TAG = "ScanBarcodeActivity";
private BarcodeDetector barcodeDetector;
private SurfaceView cameraView;
private CameraSource cameraSource;
private EditText cardNo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_barcode);
}
@Override
protected void onResume() {
cameraView = (SurfaceView) findViewById(R.id.surfaceViewCamera);
cardNo = (EditText) findViewById(R.id.editTextBarcode);
scanBarcodeCam(0);
super.onResume();
}
@Override
protected void onDestroy() {
if(cameraSource != null) {
cameraSource.stop();
cameraSource.release();
cameraSource = null;
}
super.onDestroy();
}
public void switchCam(View view) {
if(cameraSource.getCameraFacing() == CAMERA_FACING_BACK) {
cameraSource.stop();
cameraSource.release();
cameraSource = null;
scanBarcodeCam(0);
Log.i(TAG, "switchCam to front");
} else {
cameraSource.stop();
cameraSource.release();
cameraSource = null;
scanBarcodeCam(1);
Log.i(TAG, "switchCam to back");
}
}
public void scanBarcodeCam(int cam) {
if(barcodeDetector == null) {
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.EAN_13)
.build();
}
if(cam == 0) {
cameraSource = new CameraSource
.Builder(this, barcodeDetector)
.setRequestedPreviewSize(640, 480)
.setFacing(CAMERA_FACING_FRONT)
.setRequestedFps(30.0f)
.build();
} else if(cam == 1) {
cameraSource = new CameraSource
.Builder(this, barcodeDetector)
.setRequestedPreviewSize(640, 480)
.setFacing(CAMERA_FACING_BACK)
.setRequestedFps(30.0f)
.setAutoFocusEnabled(true)
.build();
}
if(!cameraView.getHolder().getSurface().isValid()) {
Log.i(TAG, "*** new SurfaceHolder");
cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
cameraSource.start(cameraView.getHolder());
} catch (IOException | RuntimeException e) {
Log.e(TAG, e.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (cameraSource != null) {
cameraSource.stop();
cameraSource.release();
cameraSource = null;
}
}
});
} else {
try {
cameraSource.start(cameraView.getHolder());
} catch(IOException e) {
Log.e(TAG, e.getMessage());
}
}
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
@Override
public void release() {
}
@Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> barcodes = detections.getDetectedItems();
if(barcodes.size() != 0) {
cardNo.post(new Runnable() {
@Override
public void run() {
cardNo.setText(barcodes.valueAt(0).displayValue);
}
});
}
}
});
}
}
非常感谢任何帮助。
所以经过两天的努力,我终于设法“炮制”了一个修复程序。不太确定为什么 setAutoFocusEnabled(true) 在某些具有自动对焦功能的设备上不起作用。
这是我的解决方法,希望它能为其他人节省一些时间:
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP) {
float x = event.getX();
float y = event.getY();
float touchMajor = event.getTouchMajor();
float touchMinor = event.getTouchMinor();
Rect touchRect = new Rect((int)(x - touchMajor / 2), (int)(y - touchMinor / 2), (int)(x + touchMajor / 2), (int)(y + touchMinor / 2));
this.submitFocusAreaRect(touchRect);
}
return super.onTouchEvent(event);
}
private void submitFocusAreaRect(final Rect touchRect) {
Field[] declaredFields = CameraSource.class.getDeclaredFields();
for (Field field : declaredFields) {
if (field.getType() == Camera.class) {
field.setAccessible(true);
try {
Camera camera = (Camera) field.get(cameraSource);
if (camera != null) {
Camera.Parameters cameraParameters = camera.getParameters();
if(cameraParameters.getMaxNumFocusAreas() == 0) {
return;
}
Rect focusArea = new Rect();
focusArea.set(touchRect.left * 2000 / cameraView.getWidth() - 1000,
touchRect.top * 2000 / cameraView.getHeight() - 1000,
touchRect.right * 2000 / cameraView.getWidth() - 1000,
touchRect.bottom * 2000 / cameraView.getHeight() - 1000);
ArrayList<Camera.Area> focusAreas = new ArrayList<>();
focusAreas.add(new Camera.Area(focusArea, 1000));
cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
cameraParameters.setFocusAreas(focusAreas);
camera.setParameters(cameraParameters);
camera.autoFocus(this);
}
} catch (IllegalAccessException | RuntimeException e) {
e.getMessage();
}
break;
}
}
}
现在我也可以用后置摄像头扫描条形码了。耶!
下面是我的条形码扫描仪activity,除了setAutoFocusEnabled(true) 之外,一切正常。它 returns 一条运行时消息说我的设备不支持自动对焦,尽管 Samsung Tab E T561 是支持自动对焦的设备。
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.SparseArray;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.EditText;
import com.google.android.gms.vision.CameraSource;
import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.io.IOException;
import static com.google.android.gms.vision.CameraSource.CAMERA_FACING_BACK;
import static com.google.android.gms.vision.CameraSource.CAMERA_FACING_FRONT;
public class ScanBarcodeActivity extends AppCompatActivity {
private String TAG = "ScanBarcodeActivity";
private BarcodeDetector barcodeDetector;
private SurfaceView cameraView;
private CameraSource cameraSource;
private EditText cardNo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_barcode);
}
@Override
protected void onResume() {
cameraView = (SurfaceView) findViewById(R.id.surfaceViewCamera);
cardNo = (EditText) findViewById(R.id.editTextBarcode);
scanBarcodeCam(0);
super.onResume();
}
@Override
protected void onDestroy() {
if(cameraSource != null) {
cameraSource.stop();
cameraSource.release();
cameraSource = null;
}
super.onDestroy();
}
public void switchCam(View view) {
if(cameraSource.getCameraFacing() == CAMERA_FACING_BACK) {
cameraSource.stop();
cameraSource.release();
cameraSource = null;
scanBarcodeCam(0);
Log.i(TAG, "switchCam to front");
} else {
cameraSource.stop();
cameraSource.release();
cameraSource = null;
scanBarcodeCam(1);
Log.i(TAG, "switchCam to back");
}
}
public void scanBarcodeCam(int cam) {
if(barcodeDetector == null) {
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.EAN_13)
.build();
}
if(cam == 0) {
cameraSource = new CameraSource
.Builder(this, barcodeDetector)
.setRequestedPreviewSize(640, 480)
.setFacing(CAMERA_FACING_FRONT)
.setRequestedFps(30.0f)
.build();
} else if(cam == 1) {
cameraSource = new CameraSource
.Builder(this, barcodeDetector)
.setRequestedPreviewSize(640, 480)
.setFacing(CAMERA_FACING_BACK)
.setRequestedFps(30.0f)
.setAutoFocusEnabled(true)
.build();
}
if(!cameraView.getHolder().getSurface().isValid()) {
Log.i(TAG, "*** new SurfaceHolder");
cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
cameraSource.start(cameraView.getHolder());
} catch (IOException | RuntimeException e) {
Log.e(TAG, e.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (cameraSource != null) {
cameraSource.stop();
cameraSource.release();
cameraSource = null;
}
}
});
} else {
try {
cameraSource.start(cameraView.getHolder());
} catch(IOException e) {
Log.e(TAG, e.getMessage());
}
}
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
@Override
public void release() {
}
@Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> barcodes = detections.getDetectedItems();
if(barcodes.size() != 0) {
cardNo.post(new Runnable() {
@Override
public void run() {
cardNo.setText(barcodes.valueAt(0).displayValue);
}
});
}
}
});
}
}
非常感谢任何帮助。
所以经过两天的努力,我终于设法“炮制”了一个修复程序。不太确定为什么 setAutoFocusEnabled(true) 在某些具有自动对焦功能的设备上不起作用。
这是我的解决方法,希望它能为其他人节省一些时间:
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP) {
float x = event.getX();
float y = event.getY();
float touchMajor = event.getTouchMajor();
float touchMinor = event.getTouchMinor();
Rect touchRect = new Rect((int)(x - touchMajor / 2), (int)(y - touchMinor / 2), (int)(x + touchMajor / 2), (int)(y + touchMinor / 2));
this.submitFocusAreaRect(touchRect);
}
return super.onTouchEvent(event);
}
private void submitFocusAreaRect(final Rect touchRect) {
Field[] declaredFields = CameraSource.class.getDeclaredFields();
for (Field field : declaredFields) {
if (field.getType() == Camera.class) {
field.setAccessible(true);
try {
Camera camera = (Camera) field.get(cameraSource);
if (camera != null) {
Camera.Parameters cameraParameters = camera.getParameters();
if(cameraParameters.getMaxNumFocusAreas() == 0) {
return;
}
Rect focusArea = new Rect();
focusArea.set(touchRect.left * 2000 / cameraView.getWidth() - 1000,
touchRect.top * 2000 / cameraView.getHeight() - 1000,
touchRect.right * 2000 / cameraView.getWidth() - 1000,
touchRect.bottom * 2000 / cameraView.getHeight() - 1000);
ArrayList<Camera.Area> focusAreas = new ArrayList<>();
focusAreas.add(new Camera.Area(focusArea, 1000));
cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
cameraParameters.setFocusAreas(focusAreas);
camera.setParameters(cameraParameters);
camera.autoFocus(this);
}
} catch (IllegalAccessException | RuntimeException e) {
e.getMessage();
}
break;
}
}
}
现在我也可以用后置摄像头扫描条形码了。耶!