PreviewActivity
package com.example.camera01;
import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.util.Size;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;
public class PreviewActivity extends AppCompatActivity {
private CameraManager mCameraManager;
private static final int REQUEST_CAMERA_PERMISSION = 1;
public static final String TAG = "LoginActivity";
HandlerThread mBackgroundThread;
Handler mBackgroundHandler;
Handler mForegroundHandler;
SurfaceView mSurfaceView;
CameraDevice mCamera;
CameraCaptureSession mCaptureSession;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onResume() {
super.onResume();
if(!checkCameraPermission())
return ;
// Start a background thread to manage camera requests
mBackgroundThread = new HandlerThread("background");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
mForegroundHandler = new Handler(getMainLooper());
mCameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
setContentView(R.layout.main);
mSurfaceView = findViewById(R.id.mainSurfaceView);
mSurfaceView.getHolder().addCallback(mSurfaceHolderCallback);
}
@Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.close();
}
}
final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
private String mCameraId;
/** Whether we received a change callback after setting our fixed surface size. */
private boolean mGotSecondCallback;
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.i(TAG, "Surface created");
mCameraId = null;
mGotSecondCallback = false;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i(TAG, "Surface destroyed");
holder.removeCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// On the first invocation, width and height were automatically set to the view's size
if (mCameraId == null) {
// Find the device's back-facing camera and set the destination buffer sizes
try {
for (String cameraId : mCameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics =
mCameraManager.getCameraCharacteristics(cameraId);
if (cameraCharacteristics.get(cameraCharacteristics.LENS_FACING) ==
CameraCharacteristics.LENS_FACING_BACK) {
Log.e(TAG, "Found a back-facing camera");
StreamConfigurationMap info = cameraCharacteristics
.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] s = info.getOutputSizes(ImageFormat.JPEG);
for (Size a :s){
Log.e(TAG, "Size : "+a);
}
// Danger, W.R.! Attempting to use too large a preview size could
// exceed the camera bus' bandwidth limitation, resulting in
// gorgeous previews but the storage of garbage capture data.
Log.i(TAG, "SurfaceView size: " +
mSurfaceView.getWidth() + 'x' + mSurfaceView.getHeight());
SurfaceHolder surfaceHolder = mSurfaceView.getHolder();
surfaceHolder.setFixedSize(1280,
720);
mCameraId = cameraId;
return;
// Control flow continues with this method one more time
// (since we just changed our own size)
}
}
} catch (CameraAccessException ex) {
Log.e(TAG, "Unable to list cameras", ex);
}
} else if (!mGotSecondCallback) {
if (mCamera != null) {
Log.e(TAG, "Aborting camera open because it hadn't been closed");
return;
}
// Open the camera device
try {
if (ActivityCompat.checkSelfPermission(PreviewActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
mCameraManager.openCamera(mCameraId, mCameraStateCallback,
mBackgroundHandler);
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to configure output surface", ex);
}
mGotSecondCallback = true;
// Control flow continues in mCameraStateCallback.onOpened()
}
}
} ;
private boolean checkCameraPermission() {
int cameraPermission1 = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
int cameraPermission2 = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (cameraPermission1 != PackageManager.PERMISSION_GRANTED || cameraPermission2 != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION);
return false;
}
return true;
}
@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) {
Log.e(TAG,"权限授予成功,可以进行拍照操作 PERMISSION_GRANTED");
// 权限授予成功,可以进行拍照操作
} else {
Log.e(TAG,"权限授予失败,无法进行拍照操作");
//
}
}
}
/**
* Calledbacks invoked upon state changes in our {@code CameraDevice}. <p>These are run on
* {@code mBackgroundThread}.</p>
*/
final CameraDevice.StateCallback mCameraStateCallback =
new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
Log.e(TAG, "Successfully opened camera");
mCamera = camera;
try {
List<OutputConfiguration> outputs = Arrays.asList(new OutputConfiguration( mSurfaceView.getHolder().getSurface()));
SessionConfiguration config = new SessionConfiguration(SessionConfiguration.SESSION_REGULAR,outputs,new Executor() {
@Override
public void execute(Runnable command) {
Log.e(TAG, "Executor execute ");
command.run();
}
} ,mCaptureSessionListener);
camera.createCaptureSession(config);
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to create a capture session", ex);
}
// Control flow continues in mCaptureSessionListener.onConfigured()
}
@Override
public void onDisconnected(CameraDevice camera) {
Log.e(TAG, "Camera was disconnected");
}
@Override
public void onError(CameraDevice camera, int error) {
Log.e(TAG, "State error on device '" + camera.getId() + "': code " + error);
}};
/**
* Callbacks invoked upon state changes in our {@code CameraCaptureSession}. <p>These are run on
* {@code mBackgroundThread}.</p>
*/
final CameraCaptureSession.StateCallback mCaptureSessionListener =
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
Log.e(TAG, "Finished configuring camera outputs");
mCaptureSession = session;
SurfaceHolder holder = mSurfaceView.getHolder();
if (holder != null) {
try {
// Build a request for preview footage
CaptureRequest.Builder requestBuilder =
mCamera.createCaptureRequest(mCamera.TEMPLATE_PREVIEW);
requestBuilder.addTarget(holder.getSurface());
CaptureRequest previewRequest = requestBuilder.build();
// Start displaying preview images
try {
session.setRepeatingRequest(previewRequest, /*listener*/null,
/*handler*/null);
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to make repeating preview request", ex);
}
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to build preview request", ex);
}
}
else {
Log.e(TAG, "Holder didn't exist when trying to formulate preview request");
}
}
@Override
public void onClosed(CameraCaptureSession session) {
Log.e(TAG, "CameraCaptureSession onClosed");
mCaptureSession = null;
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
Log.e(TAG, "Configuration error on device '" + mCamera.getId());
}};
}
layout :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#ff0000"
android:layout_height="match_parent">
<SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainSurfaceView"
android:layout_height="720px"
android:layout_width="1279px"
android:onClick="onClickOnSurfaceView" />
</RelativeLayout>
效果: