写一份完整的使用camera2扫描多张二维码并且每次扫描结束后打开闪光灯的工具类代码和调用代码
时间: 2024-03-12 08:47:07 浏览: 122
以下是使用Camera2扫描多张二维码并打开闪光灯的工具类代码和调用代码,供参考:
工具类代码:
```java
public class QRCodeScanner {
private static final String TAG = "QRCodeScanner";
private CameraManager cameraManager;
private String cameraId;
private CameraDevice cameraDevice;
private CameraCaptureSession captureSession;
private CaptureRequest.Builder captureRequestBuilder;
private ImageReader imageReader;
private HandlerThread backgroundThread;
private Handler backgroundHandler;
private Semaphore cameraOpenCloseLock = new Semaphore(1);
private Context context;
private QRCodeListener qrCodeListener;
public QRCodeScanner(Context context, QRCodeListener qrCodeListener) {
this.context = context;
this.qrCodeListener = qrCodeListener;
}
public void startScanning() {
startBackgroundThread();
openCamera();
}
public void stopScanning() {
closeCamera();
stopBackgroundThread();
}
private void startBackgroundThread() {
backgroundThread = new HandlerThread("QRCodeScanner");
backgroundThread.start();
backgroundHandler = new Handler(backgroundThread.getLooper());
}
private void stopBackgroundThread() {
backgroundThread.quitSafely();
try {
backgroundThread.join();
backgroundThread = null;
backgroundHandler = null;
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage());
}
}
private void openCamera() {
cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
try {
if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Time out waiting to lock camera opening.");
}
String[] cameraIds = cameraManager.getCameraIdList();
for (String id : cameraIds) {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id);
int facing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (facing == CameraCharacteristics.LENS_FACING_BACK) {
cameraId = id;
break;
}
}
if (cameraId == null) {
cameraId = cameraIds[0];
}
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
cameraDevice = camera;
createCameraPreviewSession();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
cameraOpenCloseLock.release();
cameraDevice.close();
cameraDevice = null;
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
cameraOpenCloseLock.release();
cameraDevice.close();
cameraDevice = null;
}
}, backgroundHandler);
} catch (CameraAccessException e) {
Log.e(TAG, e.getMessage());
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage());
}
}
private void createCameraPreviewSession() {
try {
SurfaceTexture texture = new SurfaceTexture(0);
texture.setDefaultBufferSize(640, 480);
Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
imageReader = ImageReader.newInstance(640, 480, ImageFormat.YUV_420_888, 2);
imageReader.setOnImageAvailableListener(reader -> {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
Result result = decode(data, 640, 480);
if (result != null) {
qrCodeListener.onQRCodeScanned(result.getText());
captureSession.stopRepeating();
captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
captureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
} finally {
if (image != null) {
image.close();
}
}
}, backgroundHandler);
captureRequestBuilder.addTarget(imageReader.getSurface());
cameraDevice.createCaptureSession(Arrays.asList(surface, imageReader.getSurface()), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
captureSession = session;
try {
captureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null);
} catch (CameraAccessException e) {
Log.e(TAG, e.getMessage());
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
}, backgroundHandler);
} catch (CameraAccessException e) {
Log.e(TAG, e.getMessage());
}
}
private void closeCamera() {
try {
cameraOpenCloseLock.acquire();
if (captureSession != null) {
captureSession.close();
captureSession = null;
}
if (cameraDevice != null) {
cameraDevice.close();
cameraDevice = null;
}
if (imageReader != null) {
imageReader.close();
imageReader = null;
}
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage());
} finally {
cameraOpenCloseLock.release();
}
}
private Result decode(byte[] data, int width, int height) {
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, false);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
return new MultiFormatReader().decode(bitmap);
} catch (NotFoundException e) {
return null;
}
}
public interface QRCodeListener {
void onQRCodeScanned(String result);
}
}
```
调用代码:
```java
QRCodeScanner scanner = new QRCodeScanner(this, result -> {
// 处理扫描结果
});
scanner.startScanning();
```
注意:以上代码仅供参考,具体实现可能需要根据实际情况进行修改。同时,扫描二维码需要相机权限,需要在AndroidManifest.xml中添加以下代码:
```xml
<uses-permission android:name="android.permission.CAMERA"/>
```
阅读全文