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) {<!-- --> // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. 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 & amp; & amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) {<!-- --> Log.e(TAG,"Permission granted successfully, you can take pictures PERMISSION_GRANTED"); // Permission granted successfully, you can take pictures } else {<!-- --> Log.e(TAG,"Permission grant failed, unable to take pictures"); // } } } /** * 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>
Effect: