Detailed process of Android studio Camera2 implementation

premise

TextureView.SurfaceTextureListener is an interface for monitoring the state changes of SurfaceTexture in TextureView. You can use a TextureView to display a camera preview while using the camera. By implementing the SurfaceTextureListener interface, you can start the camera preview when the SurfaceTexture is ready and stop the preview when the SurfaceTexture is destroyed.

注意: The camera must be turned on after onSurfaceTextureAvailable is ready

  • The interface is as follows:
  • (The case code is implemented in the form of implements TextureView.SurfaceTextureListener)
TextureView textureView = findViewById(R.id.texture_view);
textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
    
    
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
    
    
        // Open camera and start preview
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
    
    
        // Handle texture size change if necessary
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
    
    
        // Stop camera preview and release camera
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
    
    
        // Handle surface texture update if necessary
    }
});

1. Get the CameraManager instance

   CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

2. Get the list of available cameras

   String[] cameraIds = manager.getCameraIdList();

3. Select a camera and open it

   String cameraId = cameraIds[0];
   manager.openCamera(cameraId, new CameraDevice.StateCallback() {
    
    
       @Override
       public void onOpened(CameraDevice camera) {
    
    
           // 相机已经打开,可以进行后续操作
       }

       @Override
       public void onDisconnected(CameraDevice camera) {
    
    
           // 相机断开连接,需要释放资源
           camera.close();
       }

       @Override
       public void onError(CameraDevice camera, int error) {
    
    
           // 相机打开出错,需要释放资源
           camera.close();
       }
   }, null);

4. Create a CaptureRequest.Builder object

   CaptureRequest.Builder builder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

5. Set the parameters of the CaptureRequest.Builder object

   builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

6. Create a CaptureSession object

   camera.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
    
    
       @Override
       public void onConfigured(CameraCaptureSession session) {
    
    
           // CaptureSession已经创建,可以进行后续操作
       }

       @Override
       public void onConfigureFailed(CameraCaptureSession session) {
    
    
           // CaptureSession创建失败,需要释放资源
           camera.close();
       }
   }, null);

Seven, start preview

   session.setRepeatingRequest(builder.build(), null, null);

code example

The preview must be enabled after dynamically obtaining the permission

  • xml layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextureView
        android:id="@+id/texture_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
</RelativeLayout>
  • deal with
public class MainActivity extends AppCompatActivity implements  TextureView.SurfaceTextureListener{
    
    

    private String[] cameraIds;
    private  String cameraId;
    private CameraManager cameraManager;//从系统服务中获取相机管理器
    private TextureView textureView;
    private CameraDevice mCameraDevice;
    private CameraCaptureSession cameraCaptureSession;
    private CaptureRequest.Builder builder = null;

    private static final int ACTION_REQUEST_PERMISSIONS = 0x001;
    /**
     * 所需的所有权限信息
     */
    private static final String[] NEEDED_PERMISSIONS = new String[]{
    
    
            Manifest.permission.CAMERA,//相机
    };


    @SuppressLint({
    
    "MissingPermission", "MissingInflatedId"})
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //权限检查
        if (!checkPermissions(NEEDED_PERMISSIONS)) {
    
    
            ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS,
                    ACTION_REQUEST_PERMISSIONS);
        }

        textureView=findViewById(R.id.texture_view);
        textureView.setSurfaceTextureListener(this);//设置布局
    }

    /**
     * 权限检查
     * @param neededPermissions 需要的权限
     * @return 是否全部被允许
     */
    protected boolean checkPermissions(String[] neededPermissions) {
    
    
        if (neededPermissions == null || neededPermissions.length == 0) {
    
    
            return true;
        }
        boolean allGranted = true;
        for (String neededPermission : neededPermissions) {
    
    
            allGranted &= ContextCompat.checkSelfPermission(this, neededPermission) == PackageManager.PERMISSION_GRANTED;
        }
        return allGranted;
    }


    @Override
    public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
    
    
        //布局初始化完成,打开相机
       if (checkPermissions(NEEDED_PERMISSIONS)) {
    
    
            openCamera2();
        }
    }

    @SuppressLint("MissingPermission")
    private void openCamera2(){
    
    
        //一、获取cameraManager
        cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
    
    
            cameraIds = cameraManager.getCameraIdList();//获取摄像机id的集合
            cameraId = cameraIds[0];
            cameraManager.openCamera(cameraId,callback,null);
        } catch (Exception e) {
    
    
            throw new RuntimeException(e);
        }
    }

    CameraDevice.StateCallback callback=new CameraDevice.StateCallback() {
    
    
        @Override
        public void onOpened(@NonNull CameraDevice cameraDevice) {
    
    
            mCameraDevice = cameraDevice;
            createCameraPreviewSession();
        }
        @Override
        public void onDisconnected(@NonNull CameraDevice cameraDevice) {
    
    

        }

        @Override
        public void onError(@NonNull CameraDevice cameraDevice, int i) {
    
    

        }
    };

    private void createCameraPreviewSession() {
    
    
        try {
    
    
            SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
//            surfaceTexture.setDefaultBufferSize(textureView.getWidth(), textureView.getHeight());
            surfaceTexture.setDefaultBufferSize(640, 480);
//            surfaceTexture.setDefaultBufferSize(480,640 );
            Surface previewSurface = new Surface(surfaceTexture);
            builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            builder.addTarget(previewSurface);
            mCameraDevice.createCaptureSession(Arrays.asList(previewSurface), new CameraCaptureSession.StateCallback() {
    
    
                @Override
                public void onConfigured(CameraCaptureSession session) {
    
    
                    cameraCaptureSession = session;
                    try {
    
    
                        cameraCaptureSession.setRepeatingRequest(builder.build(), null, null);
                    } catch (CameraAccessException e) {
    
    
                        e.printStackTrace();
                    }
                }
                @Override
                public void onConfigureFailed(CameraCaptureSession session) {
    
    
                    Toast.makeText(MainActivity.this, "Failed to create camera capture session", Toast.LENGTH_SHORT).show();
                }
            }, null);
        } catch (CameraAccessException e) {
    
    
            e.printStackTrace();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    
    
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
    
    
            case ACTION_REQUEST_PERMISSIONS: {
    
    
                // 如果请求被取消,结果数组将为空
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    
    
                    // 授权成功,执行相关操作
                    //打开相机
                    openCamera2();
                } else {
    
    
                    // 授权失败,禁用相关功能或显示提示信息

                }
                return;
            }
            // 处理其他权限请求
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
    
    

    }

    @Override
    public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture  surfaceTexture) {
    
    
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) {
    
    

    }
    @Override
    protected void onResume() {
    
    
        super.onResume();
    }

}

Guess you like

Origin blog.csdn.net/afufufufu/article/details/130699897