Of course. Here is my coe snippet:
private void startCamera() {
viewBinding.viewFinder.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
singleTapFocus(event);
v.performClick();
return true;
}
});
try {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
StreamConfigurationMap configurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
// Size[] outputSizes = configurationMap.getOutputSizes(ImageFormat.YUV_420_888);
Size[] outputSizes = configurationMap.getOutputSizes(ImageFormat.PRIVATE);
for (Size outputSize : outputSizes) {
Log.d("TAG", "cameraId:"+cameraId+",支持的分辨率:"+outputSize);
}
}
}catch (Exception e){
e.printStackTrace();
}
// 将Camera的生命周期和Activity绑定在一起(设定生命周期所有者),这样就不用手动控制相机的启动和关闭。
ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
try {
// 将你的相机和当前生命周期的所有者绑定所需的对象
processCameraProvider = cameraProviderFuture.get();
bindCamera(processCameraProvider);
// 创建一个Preview 实例,并设置该实例的 surface
} catch (Exception e) {
Log.e(Configuration.TAG, "用例绑定失败!" + e);
}
}, ContextCompat.getMainExecutor(this));
}
@OptIn(markerClass = ExperimentalCamera2Interop.class)
private void bindCamera(ProcessCameraProvider processCameraProvider) {
try {
//选择特定摄像头
String targetPhysicalCamera = "7";
CameraSelector cameraSelector;
if(MainActivity.GLOBAL_SELECTED_CAMERA.equals("Default") || !SettingActivity.GLOBAL_DEVICE_CAMERA){
cameraSelector = selectExternalOrBestCamera(processCameraProvider);
viewBinding.switchCameraButton.setEnabled(true);
}
else{
cameraSelector = selectLogicalCameraWithPhysicalCameraID(targetPhysicalCamera);
viewBinding.switchCameraButton.setEnabled(false);
}
// 创建一个Preview 实例,并设置该实例的 surface 提供者(provider)。
Preview.Builder previewBuilder = new Preview.Builder();
Preview preview = previewBuilder
//.setPreviewStabilizationEnabled(true)
.build();
preview.setSurfaceProvider(viewBinding.viewFinder.getSurfaceProvider());
// 创建拍照所需的实例
ImageCapture.Builder imageCaptureBuilder = new ImageCapture.Builder();
if(!MainActivity.GLOBAL_SELECTED_CAMERA.equals("Default") && SettingActivity.GLOBAL_DEVICE_CAMERA){
// 通过 Camera2Interop 设置物理摄像头 ID
Camera2Interop.Extender imageCaptureExtender =
new Camera2Interop.Extender(imageCaptureBuilder)
.setPhysicalCameraId(targetPhysicalCamera);
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
Camera2Interop.Extender imageCaptureExtender = new Camera2Interop.Extender(imageCaptureBuilder).setPhysicalCameraId(targetPhysicalCamera);
}
imageCapture = imageCaptureBuilder.build();
Boolean isPreviewStabilizationSupported = Preview.getPreviewCapabilities(processCameraProvider.getCameraInfo(cameraSelector)).isStabilizationSupported();
// 设置预览帧分析
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
.setResolutionSelector(new ResolutionSelector.Builder().setResolutionStrategy(ResolutionStrategy.HIGHEST_AVAILABLE_STRATEGY).build())
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();
imageAnalysis.setAnalyzer(cameraExecutor, new ImageAnalysis.Analyzer() {
@SuppressLint("UnsafeOptInUsageError")
@Override
public void analyze(@NonNull ImageProxy image) {
Log.d(Configuration.TAG, "Image's stamp is " +
"cameraId:"+Camera2CameraInfo.from(camera.getCameraInfo()).getCameraId()+
Objects.requireNonNull(image.getImage()).getTimestamp() +
"; 尺寸:" + image.getWidth() + "*" + image.getHeight()+
";\nformat:"+image.getFormat());
Log.d("TAG", "startCatptureImages:"+startCatptureImages);
long start = System.currentTimeMillis();
try {
if (image == null || image.getImage() == null) {
return;
}
}
});
// 重新绑定用例前先解绑
processCameraProvider.unbindAll();
camera = processCameraProvider.bindToLifecycle(MultiActivity.this,
cameraSelector,
preview,
imageCapture,
imageAnalysis/*,
videoCapture*/);
//开启防抖
toggleStabilization(previewBuilder);
viewBinding.swFlashlight.setChecked(true);
// 设置定时器每隔1秒自动对焦
//startAutoFocus();
startAutoFocusLoop();
} catch (Exception e) {
Log.e(Configuration.TAG, "用例绑定失败!" + e);
}
}
private int count = -1;
//选择特定摄像头
@SuppressLint("UnsafeOptInUsageError")
public CameraSelector selectExternalOrBestCamera(ProcessCameraProvider provider) {
//这里获取设备的摄像头信息列表,里面就包含有多少个摄像头
List<Camera2CameraInfo> cam2Infos = provider.getAvailableCameraInfos().stream().map(it -> {
return Camera2CameraInfo.from(it);
}).collect(Collectors.toList());
if (cam2Infos.isEmpty()){
return CameraSelector.DEFAULT_BACK_CAMERA;
}else {
count++;
if (count>=cam2Infos.size()) count = 0;
return new CameraSelector.Builder()
.addCameraFilter(cameraInfos -> {
return cameraInfos.stream().filter(camInfo -> {
String thisCamId = Camera2CameraInfo.from(camInfo).getCameraId();
// Log.d(TAG, "selectExternalOrBestCamera: ${cam2Infos[count].cameraId},${camInfo.implementationType}")
viewBinding.tvMsg.setText("切换摄像头:"+cam2Infos.get(count).getCameraId()+"/"+cam2Infos.size());
return thisCamId.equals(cam2Infos.get(count).getCameraId());
}).collect(Collectors.toList());
})
.build();
}
}
public CameraSelector selectLogicalCameraWithPhysicalCameraID(String targetPhysicalCameraId) {
try {
cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
String[] cameraIds = cameraManager.getCameraIdList();
List<String> backCameraIds = new ArrayList<>();
for (String id : cameraIds) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(id);
if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) != CameraCharacteristics.LENS_FACING_BACK)
continue;
backCameraIds.add(id);
}
String targetLogicalCameraId = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
List<String> logicCameraIds = new ArrayList<>();
for (String id : backCameraIds) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(id);
Set<String> physicalCameraIds = cameraCharacteristics.getPhysicalCameraIds();
int[] available = cameraCharacteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
for (int i : available) {
if (i == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
logicCameraIds.add(id);
}
}
}
for (String id : logicCameraIds) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(id);
Set<String> physicalCameraIds = cameraCharacteristics.getPhysicalCameraIds();
if (physicalCameraIds.contains(targetPhysicalCameraId)) {
targetLogicalCameraId = id;
return new CameraSelector.Builder()
.addCameraFilter(cameraInfos -> {
return cameraInfos.stream().filter(camInfo -> {
String thisCamId = Camera2CameraInfo.from(camInfo).getCameraId();
return thisCamId.equals(id);
}).collect(Collectors.toList());
})
.setPhysicalCameraId(targetPhysicalCameraId)
.build();
}
else{
continue;
}
}
}
}
catch (Exception e){
e.printStackTrace();
}
return CameraSelector.DEFAULT_BACK_CAMERA;
}
@OptIn(markerClass = ExperimentalCamera2Interop.class)
@SuppressLint("UnsafeExperimentalUsageError")
private CameraSelector getCameraSelector(String cameraId) {
return new CameraSelector.Builder()
.addCameraFilter(cameras -> {
List<CameraInfo> result = new ArrayList<>();
for (CameraInfo cameraInfo : cameras) {
if (cameraId.equals(Camera2CameraInfo.from(cameraInfo).getCameraId())) {
result.add(cameraInfo);
}
}
return result;
})
.build();
}
private void switchCamera(){
//切换摄像头
;
bindCamera(processCameraProvider);
}