赞
踩
Android CameraX 是一个 Jetpack 支持库,旨在简化相机应用的开发工作。它提供了一致且易用的API接口,适用于大多数Android设备,并可向后兼容至Android 5.0(API级别21)。
CameraX解决了在多种设备上实现相机功能时所遇到的兼容性问题,大大减少了需要编写的设备专属代码量。同时,它还通过提供一种基于用例的、具有生命周期感知能力的方式,简化了相机功能的开发。
implementation("androidx.camera:camera-core:1.3.4")
implementation("androidx.camera:camera-camera2:1.3.4")
implementation("androidx.camera:camera-lifecycle:1.3.4")
implementation("androidx.camera:camera-video:1.3.4")
implementation("androidx.camera:camera-view:1.3.4")
新建一个activity_photo.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xhead="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#005dd7" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:layout_margin="20dp" android:background="@drawable/shape_common_dialog_bg" android:orientation="vertical"> <androidx.camera.view.PreviewView android:layout_width="640dp" android:layout_height="600dp" android:id="@+id/viewFinder" /> <Button android:layout_marginTop="10dp" android:background="@drawable/shape_login_button" android:id="@+id/image_capture_button" android:layout_width="300dp" android:layout_height="wrap_content" android:elevation="2dp" android:text="拍照" /> </LinearLayout>
public class PhotoActivity implements View.OnClickListener {
//图片捕获
private ImageCapture imageCapture;
//
private ProcessCameraProvider cameraProvider;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo);
}
应用需要获得用户授权才能打开相机。
首先在AndroidManifest.xml中声明
<uses-permission android:name="android.permission.CAMERA" />
所以在onCreate(@Nullable Bundle savedInstanceState)方法中增加:
protected void onCreate(@Nullable Bundle savedInstanceState){ String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}; if (allPermissionsGranted(permissions, this)) { startCamera(); } else { ActivityCompat.requestPermissions(this, permissions, REQUEST_CAMERA_PERMISSION); } } public boolean allPermissionsGranted(String[] permissions, Context context) { for (String permission : permissions) { int checkSelfPermission = ContextCompat.checkSelfPermission(context, permission); if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, permissions, REQUEST_CAMERA_PERMISSION); } } return true; }
当然用户存在不同意的情况,此时可以重写 onRequestPermissionsResult 方法以处理权限请求结果:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 权限已被授予,可以执行相机相关操作
startCamera();
} else {
// 权限被拒绝,提示用户需要授权
Toast.makeText(this, "需要相机权限才能使用此功能", Toast.LENGTH_SHORT).show();
}
}
}
我们打开前置摄像头:
private void startCamera() { ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this); cameraProviderFuture.addListener(() -> { try { cameraProvider = cameraProviderFuture.get(); //前置摄像头 CameraSelector cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA; Preview preview = new Preview.Builder().build(); // 构建预览用例 preview.setSurfaceProvider(bd.viewFinder.getSurfaceProvider()); // 构建图片捕获用例 imageCapture = new ImageCapture.Builder().build(); // 将用例绑定到相机 cameraProvider.bindToLifecycle( PersonPhotoActivity.this, cameraSelector, preview, imageCapture); } catch (ExecutionException | InterruptedException e) { throw new RuntimeException(e); } }, ContextCompat.getMainExecutor(this)); }
配置avd的前置摄像头为虚拟模式:
启动项目查看页面:
当拍照按钮被点击时调用takePhoto 方法,这里我们建立了一个file对象临时保存当前照片,之后我们就可以自由使用该照片:
@Override
public void onClick(View view) {
if (view.getId() == R.id.image_capture_button) {
takePhoto(view);
}
}
private void takePhoto(View view) { File file = new File(getContext().getExternalCacheDir() + File.separator + System.currentTimeMillis() + ".png"); //创建包文件的数据,比如创建文件 ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(file).build(); //开始拍照 imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(this), new ImageCapture.OnImageSavedCallback() { @Override public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) { // 关闭相机并释放资源 cameraProvider.unbindAll(); // file.getPath() //做业务 //。。。。 } @Override public void onError(@NonNull ImageCaptureException exception) { Log.d(TAG, Objects.requireNonNull(exception.toString())); Toast.makeText(PersonPhotoActivity.this, "照片保存失败", Toast.LENGTH_SHORT).show(); } }); }
代码分析:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。