实现 camera2扫码功能
时间: 2023-12-30 21:17:01 浏览: 136
windows系统 调用摄像头 实现扫码
要实现 camera2 扫码功能,可以按照以下步骤进行操作:
1. 在 AndroidManifest.xml 中添加相机权限:
```xml
<uses-permission android:name="android.permission.CAMERA" />
```
2. 在布局文件中添加 SurfaceView 组件,用于显示相机预览:
```xml
<SurfaceView
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
```
3. 在 Activity 中获取 SurfaceView 组件,并在 onResume() 方法中打开相机:
```java
private SurfaceView mPreview;
private CameraManager mCameraManager;
private CameraDevice mCameraDevice;
private CameraCaptureSession mCaptureSession;
private CaptureRequest.Builder mPreviewRequestBuilder;
private HandlerThread mBackgroundThread;
private Handler mBackgroundHandler;
@Override
protected void onResume() {
super.onResume();
startBackgroundThread();
mPreview = findViewById(R.id.camera_preview);
SurfaceHolder holder = mPreview.getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
openCamera();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// do nothing
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
closeCamera();
}
});
}
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread("CameraBackground");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
private void openCamera() {
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
String cameraId = mCameraManager.getCameraIdList()[0];
mCameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
mCameraDevice = camera;
createCameraPreviewSession();
}
@Override
public void onDisconnected(CameraDevice camera) {
camera.close();
mCameraDevice = null;
}
@Override
public void onError(CameraDevice camera, int error) {
camera.close();
mCameraDevice = null;
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void closeCamera() {
if (mCaptureSession != null) {
mCaptureSession.close();
mCaptureSession = null;
}
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
}
private void createCameraPreviewSession() {
try {
Surface surface = mPreview.getHolder().getSurface();
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
if (mCameraDevice == null) {
return;
}
mCaptureSession = session;
try {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
// do nothing
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
```
4. 添加扫码功能,可以使用 zxing 库,将其添加到项目的依赖中:
```groovy
dependencies {
implementation 'com.google.zxing:core:3.4.1'
}
```
5. 在 Activity 中添加扫码方法:
```java
private static final int REQUEST_CODE_SCAN = 0x0000;
private void startScan() {
Intent intent = new Intent(this, CaptureActivity.class);
startActivityForResult(intent, REQUEST_CODE_SCAN);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_SCAN && resultCode == RESULT_OK) {
String result = data.getStringExtra(CaptureActivity.EXTRA_RESULT);
// do something with the scan result
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
```
6. 在扫码界面中启动相机,并在扫描到二维码时返回结果:
```java
private SurfaceView mPreview;
private Camera mCamera;
private Handler mHandler;
private boolean mIsScanning = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan);
mHandler = new Handler();
mPreview = findViewById(R.id.camera_preview);
SurfaceHolder holder = mPreview.getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
startCamera();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// do nothing
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
stopCamera();
}
});
}
private void startCamera() {
try {
mCamera = Camera.open();
Camera.Parameters params = mCamera.getParameters();
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
mCamera.setParameters(params);
mCamera.setPreviewDisplay(mPreview.getHolder());
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (mIsScanning) {
Camera.Size size = camera.getParameters().getPreviewSize();
int width = size.width;
int height = size.height;
Image barcode = new Image(width, height, "Y800");
barcode.setData(data);
Result result = new MultiFormatReader().decode(new BinaryBitmap(new HybridBinarizer(barcode)));
if (result != null) {
mIsScanning = false;
Intent intent = new Intent();
intent.putExtra(EXTRA_RESULT, result.getText());
setResult(RESULT_OK, intent);
finish();
}
}
}
});
mCamera.startPreview();
mIsScanning = true;
} catch (IOException e) {
e.printStackTrace();
}
}
private void stopCamera() {
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
```
这样,就可以实现 camera2 扫码功能了。
阅读全文