一、首先导入相关权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-featureandroid:name="android.hardware.camera"android:required="true" /><uses-permission android:name="android.permission.CAMERA" /><!-- 这个权限允许应用程序录制音频。 --><uses-permission android:name="android.permission.RECORD_AUDIO" />
二、导入依赖
// CameraX 相关依赖def cameraxVersion = "1.1.0-alpha05"implementation "androidx.camera:camera-core:${cameraxVersion}"implementation "androidx.camera:camera-camera2:${cameraxVersion}"implementation "androidx.camera:camera-lifecycle:${cameraxVersion}"implementation 'androidx.camera:camera-view:1.0.0-alpha25'
三、Activity
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.Preview;
import androidx.camera.core.VideoCapture;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;import com.google.common.util.concurrent.ListenableFuture;import org.json.JSONException;
import org.json.JSONObject;import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private static final int REQUEST_CODE_RECORD_AUDIO_PERMISSION = 1001;private static final int REQUEST_CODE_CAMERA_PERMISSION = 1002;private static final int REQUEST_CODE_STORAGE_PERMISSION = 1003;private ListenableFuture<ProcessCameraProvider> processCameraProviderListenableFuture;private PreviewView previewView;private Button btn_photograph; //拍照private ImageCapture imageCapture;private CameraSelector cameraSelector;private TextView tv;private boolean isUsingFrontCamera = false; // 默认使用前置摄像头@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);previewView = findViewById(R.id.previewView);btn_photograph = findViewById(R.id.btn_photograph);tv = findViewById(R.id.tv);btn_photograph.setOnClickListener(this);// 检查权限if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ||ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_RECORD_AUDIO_PERMISSION);} else {initializeCamera();}}// 初始化相机private void initializeCamera() {processCameraProviderListenableFuture = ProcessCameraProvider.getInstance(this);processCameraProviderListenableFuture.addListener(() -> {try {ProcessCameraProvider processCameraProvider = processCameraProviderListenableFuture.get();start(processCameraProvider);} catch (Exception e) {throw new RuntimeException(e);}}, ContextCompat.getMainExecutor(this));}@SuppressLint("RestrictedApi")private void start(ProcessCameraProvider processCameraProvider) {processCameraProvider.unbindAll();cameraSelector = new CameraSelector.Builder().requireLensFacing(isUsingFrontCamera ? CameraSelector.LENS_FACING_FRONT : CameraSelector.LENS_FACING_BACK).build();Preview preview = new Preview.Builder().build();preview.setSurfaceProvider(previewView.getSurfaceProvider());imageCapture = new ImageCapture.Builder().setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY).build();processCameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture);}@SuppressLint("RestrictedApi")@Overridepublic void onClick(View view) {if (view.getId() == R.id.btn_photograph) {captureImage();}}// 拍照private void captureImage() {long timeStamp = System.currentTimeMillis();ContentValues contentValues = new ContentValues();contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, timeStamp);contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");imageCapture.takePicture(new ImageCapture.OutputFileOptions.Builder(getContentResolver(),MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues).build(),ContextCompat.getMainExecutor(this),new ImageCapture.OnImageSavedCallback() {@Overridepublic void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {Toast.makeText(MainActivity.this, "拍照保存成功", Toast.LENGTH_SHORT).show();Uri savedUri = outputFileResults.getSavedUri();if (savedUri != null) {try {InputStream inputStream = getContentResolver().openInputStream(savedUri); // 打开输入流if (inputStream != null) {ExifInterface exifInterface = new ExifInterface(inputStream); // 创建ExifInterface对象String datetime = exifInterface.getAttribute(ExifInterface.TAG_DATETIME); // 获取拍摄时间String make = exifInterface.getAttribute(ExifInterface.TAG_MAKE); // 获取相机制造商String model = exifInterface.getAttribute(ExifInterface.TAG_MODEL); // 获取相机型号String focalLength = exifInterface.getAttribute(ExifInterface.TAG_FOCAL_LENGTH); // 获取焦距String aperture = exifInterface.getAttribute(ExifInterface.TAG_APERTURE); // 获取光圈Log.d("EXIF Info", "获取拍摄时间: " + datetime);Log.d("EXIF Info", "获取相机制造商: " + make);Log.d("EXIF Info", "获取相机型号: " + model);Log.d("EXIF Info", "获取焦距: " + focalLength);Log.d("EXIF Info", " 获取光圈: " + aperture);tv.setText("获取拍摄时间: " + datetime+"\n"+"获取相机制造商: " + make+"\n"+"获取相机型号: " + model+"\n"+"获取焦距: " + focalLength+"\n"+" 获取光圈: " + aperture);inputStream.close(); // 关闭输入流}} catch (IOException e) {e.printStackTrace();}}}@Overridepublic void onError(@NonNull ImageCaptureException exception) {Toast.makeText(MainActivity.this, "拍照保存失败: " + exception.getMessage(), Toast.LENGTH_SHORT).show();}});}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == REQUEST_CODE_RECORD_AUDIO_PERMISSION) {for (int i = 0; i < permissions.length; i++) {if (permissions[i].equals(Manifest.permission.RECORD_AUDIO) && grantResults[i] == PackageManager.PERMISSION_GRANTED) {// 录音权限已授予if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ||ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_CAMERA_PERMISSION);} else {initializeCamera();}} else if (permissions[i].equals(Manifest.permission.RECORD_AUDIO) && grantResults[i] != PackageManager.PERMISSION_GRANTED) {Toast.makeText(this, "录音权限被拒绝", Toast.LENGTH_SHORT).show();}}} else if (requestCode == REQUEST_CODE_CAMERA_PERMISSION) {for (int i = 0; i < permissions.length; i++) {if ((permissions[i].equals(Manifest.permission.CAMERA) || permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) &&grantResults[i] != PackageManager.PERMISSION_GRANTED) {Toast.makeText(this, "相机或存储权限被拒绝", Toast.LENGTH_SHORT).show();}}}}
}
注意:这点只是简单获取 ,想要获取更多信息,可以自行修改
四、布局代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:divider="@color/black"android:orientation="vertical"tools:context=".MainActivity"><androidx.camera.view.PreviewViewandroid:id="@+id/previewView"android:layout_width="match_parent"android:layout_height="200dp"/><Buttonandroid:id="@+id/btn_photograph"android:layout_width="match_parent"android:layout_height="100dp"android:text="拍照" /><TextViewandroid:id="@+id/tv"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="111"/></LinearLayout>
效果图