下面是我的条码扫描器活动,除了setAutoFocusEnabled(true)之外,一切正常.它在运行时返回一条消息,说明我的设备不支持自动对焦,尽管三星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() { @Override public void release() { } @Override public void receiveDetections(Detector.Detections detections) { final SparseArray barcodes = detections.getDetectedItems(); if(barcodes.size() != 0) { cardNo.post(new Runnable() { @Override public void run() { cardNo.setText(barcodes.valueAt(0).displayValue); } }); } } }); } }
任何帮助将受到高度赞赏.
所以经过两天的奋斗,我终于设法"炮制"了一个修复.但Android开发团队应该认真研究为什么setAutoFocusEnabled(true)在使用Auto Focus的设备上不起作用.
这是我的修复,希望它能节省一些时间:
@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); ArrayListfocusAreas = 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; } } }
现在我也可以使用后置摄像头扫描条形码.好极了!