在Android中设置相机预览功能涉及多个关键步骤和技术点,以下是详细实现方案和扩展知识:
1. 添加权限声明
在`AndroidManifest.xml`中声明相机和存储权限:
xml
2. 动态权限请求
Android 6.0+需在运行时请求权限:
java
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
3. 使用Camera2 API(推荐)
- 创建预览会话:通过`CameraManager`获取摄像头ID,使用`CameraDevice.StateCallback`设备状态。
- 配置Surface:将`SurfaceView`或`TextureView`的Surface作为预览目标。
java
SurfaceTexture texture = textureView.getSurfaceTexture();
texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
Surface previewSurface = new Surface(texture);
4. 图像捕获配置
- 创建`CaptureRequest.Builder`,设置`TEMPLATE_PREVIEW`模式并添加Surface:
java
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(previewSurface);
cameraDevice.createCaptureSession(Arrays.asList(previewSurface, imageReader.getSurface()), sessionCallback, null);
5. 兼容性处理
- Camera1 API备用方案:旧设备需使用`android.hardware.Camera`类,通过`setPreviewDisplay()`或`setPreviewTexture()`绑定视图。
- 分辨率适配:通过`StreamConfigurationMap`获取设备支持的预览尺寸,选择最佳比例(如16:9)。
6. 横竖屏适配
- 根据屏幕方向调整预览旋转角度:
java
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
7. 高级功能扩展
- 实时图像处理:通过`ImageReader`获取YUV或RAW数据,结合OpenCV实现边缘检测等算法。
- HDR/夜景模式:调用`TEMPLATE_STILL_CAPTURE`并配置`CONTROL_SCENE_MODE`。
- 多摄像头协同:Android 9+支持逻辑摄像头切换(`CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA`)。
8. 性能优化
- 使用`TextureView`替代`SurfaceView`实现动态变形(需权衡GPU消耗)。
- 设置合适的缓冲队列大小(`Camera2 API`的`MAX_IMAGES`参数)。
- 后台线程处理图像数据,避免主线程阻塞。
常见问题解决方案:
预览拉伸:检查视图宽高比与预览尺寸是否匹配,可通过`setAspectRatio()`调整。
对焦失败:添加`CONTROL_AF_MODE_CONTINUOUS_PICTURE`自动对焦模式。
延迟过高:降低预览分辨率或使用`YUV_420_888`格式替代JPEG。
扩展知识:
Android 12引入的`Camera2Extender`支持厂商扩展功能(如长焦镜头调优),而`CameraX`库进一步简化了API调用,适合快速集成基础功能。对于专业级应用,需关注`DNG`原始数据捕获和`Camera2`的`SessionConfiguration`高级配置。