二.Camera2 启动Camera设备取景过程


说明:
1、点击Camera 应用后,进入CameraActivity.java,完成初始化,包括判断是哪种模式(拍照,摄像,全景拍照)。我们这里说的是拍照模式。
判断此模式是在CameraActivity.java的onCreate 方法里,调用setModuleFromIndex 方法,通过下面语句赋值  mCurrentModule = new PhotoModule();
其中mCurrentModule  是private CameraModule mCurrentModule;
关于CameraModule参考后面章节。
2、进入CameraActivity.java 的 onResume方法,执行下面语句
        mCurrentModule.onResumeAfterSuper();
   在onResumeAfterSuper 方法里调用prepareCamera方法,来打开Camera,语句如下:
        mCameraDevice = CameraUtil.openCamera(
                mActivity, mCameraId, mHandler,
                mActivity.getCameraOpenErrorCallback());
     其中mCameraDevice是com.android.camera.CameraManager.CameraProxy;的实例。
        CameraUtil 属于公共的API,用于给不同模块提供对Camera的不同操作。
在它openCamera 方法里,执行下面语句:
CameraHolder.instance().open(handler, cameraId, cb);
其中CameraHolder,典型的单例模式。目的就是控制,相机开启的只有能是一个。再次开启前,要确认上次已经销毁。
3、在CameraHolder 的open 方法里,执行语句
                   mCameraDevice = CameraManagerFactory
                        .getAndroidCameraManager().cameraOpen(handler, cameraId, cb);
   CameraManagerFactory 调用的工厂模式,创建一个AndroidCameraManagerImpl 实例。并调用它的cameraOpen方法。
   AndroidCameraManagerImpl.java 是CameraManager 接口的实现。目的就是对Camera 进行管理。通过与
frameworks/base/core/java/android/hardware/Camera.java 交互,实现软件控制硬件Camera的功能。
      在cameraOpen方法中执行
       mCameraHandler.obtainMessage(OPEN_CAMERA, cameraId, 0,
                CameraOpenErrorCallbackForward.getNewInstance(
                        handler, callback)).sendToTarget();.
      其中mCameraHandler 继承Handler 重写了handleMessage 方法。其中语句
                 case OPEN_CAMERA:
                        mCamera = android.hardware.Camera.open(msg.arg1);
                        return;
                 就是通过frameworks的Camera.java 类,来调用Camera 驱动层,来开Camera设备的。
4、设备开启后,调用在prepareCamera方法里,调用startPreview();在这里获取SurfaceTexture 的实例。第一次进入,获取的是空,那是因为没有调用PhotoUI的onSurfaceTextureAvailable的方法。这个方法是底层直接调用。在这个方法里语句
mController.onPreviewUIReady();
其中mController 属于PhotoController接口的实例,而PhotoModule 实现了它的方法。在初始化的时候,赋值给它。因此直接调用的是PhotoModule的onPreviewUIReady 方法。在这个方法里,重新调用startPreview();然后获取的SurfaceTexture的实例。通过  mCameraDevice.setPreviewTexture(st);方法,讲设备获取的图像,呈现在手机屏幕。

注意:在AndroidManifest.xml 中添加Camera 权限。
<uses-permission android:name="android.permission.CAMERA" />
5、取景遇到的问题的
   当我们取景后,发现获取的图像在屏幕上旋转90度。如何让取景跟屏幕保持一致?
   CameraActivity 类中重写onConfigurationChanged 方法。
   CameraModule 接口中,增加onConfigurationChanged 方法声明,并且在PhotoModule类中实现。调用PhotoModule 中setDisplayOrientation方法。在setDisplayOrientation方法中调用CameraUtil类中的getDisplayRotation和getDisplayOrientation方法,获取了屏幕与取景需要的方向。
    通过mCameraDevice.setDisplayOrientation(mCameraDisplayOrientation); 来设置Camera 设备的显示角度。

       6、关闭相机
           当我们关闭相机的时候,调用CameraActivity的onPause 方法,然后调用PhotoModule的onPauseAfterSuper方法。在这个方法里stopPreview(); 方法和closeCamera();方法。其中stopPreview(); 是停止设备Camera;closeCamera();是release 设备Camera。一定要release ,否则再次进入Camera 会报错。


### Camera API 2 官方文档和教程 官方文档提供了详尽的信息来帮助开发者理解和使用Camera API 2。该API位于`android.hardware.camera2`包内,旨在替代过时的`Camera`类[^5]。 #### 打开相机与初始化设置 为了启动并配置摄像头,在应用中需先获取到`CameraManager`实例,用于枚举可用摄像头条目以及查询其特性。接着选取目标设备ID后调用`openCamera()`方法建立连接。此过程涉及权限验证及异步回调处理机制[^1]。 ```java // 获取CameraManager服务对象 CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); String[] cameraIdList; try { cameraIdList = manager.getCameraIdList(); } catch (CameraAccessException e) { // 处理异常情况... } ``` #### 创建会话并开启预览流 一旦成功打开了指定的camera device,则应创建一个CaptureSession以便提交捕获请求序列给硬件层执行。通常情况下,应用程序希望立即显示实时图像数据作为取景器界面的一部分;此时可通过SurfaceView组件接收来自HAL层传递过来的画面帧缓冲区,并将其呈现出来供用户查看[^3]。 ```java // 设置预览surface SurfaceTexture texture = mTextureView.getSurfaceTexture(); texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); final Surface surface = new Surface(texture); mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mPreviewRequestBuilder.addTarget(surface); mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { try { updatePreview(session); } catch (Exception ex) { Log.e(TAG, "Error during capture session configuration", ex); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession session) { Toast.makeText(getApplicationContext(), "Configuration change", Toast.LENGTH_SHORT).show(); } }, null /* handler */); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值