Android 5.0(Lollipop)增加了Camera2 API,并将原有的Camera API标记为废弃。对于原有的Camera API来说,Camera2重新定义了相机的API,也重构了相机API的架构。在Camera2中其主要思想是基于会话模式和事件驱动与相机实现交互,对于预览、拍照、录制等操作都是在会话的基础下请求某种类型的会话操作。
下面一起看下camera2的操作:
- 相机初始化
我们知道要使用相机,首先我们需要获得相关的权限,主要是在manifest中定义,其次在Android6.0还需要动态获取权限。
- 在manifest中定义需要的权限
1
<uses-permission android:name="android.permission.CAMERA" />
如果要保存照片、录制视频,还需要两个权限:
1 | <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
相机功能:相机特性,如:
1 | <uses-feature android:name="android.hardware.camera" /> |
- 动态权限申请
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22private final String[] VIDEO_PERMISSIONS = {
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
};
//......
if (!hasPermissionsGranted(getApplicationContext(), VIDEO_PERMISSIONS)) {
requestPermissions(VIDEO_PERMISSIONS, 1);
return;
}
//......
hasPermissionsGranted(Context context, String[] permissions) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission)
!= PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
以上基础工作好了基本可以开始对相机操作了。
1 | //初始化相机设备 |
开启相机预览
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56/**
* 开始预览,此处创建一个捕获视频信息的请求,以此来获取一个会话session,在获取会话时监听其配置状态,一旦成功,则此时通过会话构建一个重复预览的请求;
*/
private void takePreview() {
try {
closePreviewSession();
SurfaceTexture surfaceTexture = surfaceView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Log.e(TAG, "preview SurfaceTexture buffer size is width:" + mPreviewSize.getWidth() + " height :" + mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
List<Surface> surfaces = new ArrayList<>();
surfaces.add(previewSurface);
surfaces.add(imageReader.getSurface());
// 创建CameraCaptureSession,该对象负责管理处理预览请求和拍照请求
mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() //
{
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
Log.d("onConfigured", "onConfigured");
if (null == mCameraDevice) return;
// 当摄像头已经准备好时,开始显示预览
mCameraCaptureSession = cameraCaptureSession;
updatePreView();
}
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
Log.d("onConfigureFailed", "onConfigureFailed");
Toast.makeText(ImageShowActivity.this, "配置失败", Toast.LENGTH_SHORT).show();
}
}, childHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 更新预览视图,构建一个TEMPLATE_PREVIEW捕获请求,此时是对会话进行设置!!!setRepeatingRequest!!!
*/
private void updatePreView() {
try {
// 创建预览需要的CaptureRequest.Builder
CaptureRequest.Builder mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// 将SurfaceView的surface作为CaptureRequest.Builder的目标
SurfaceTexture surfaceTexture = surfaceView.getSurfaceTexture();
Log.e(TAG, "update preview SurfaceTexture buffer size is width:" + mPreviewSize.getWidth() + " height :" + mPreviewSize.getHeight());
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
mPreviewBuilder.addTarget(previewSurface);
mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
mCameraCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), null, childHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}拍照
1 | /** |
- 录制视频
1 | /** |
手机支持的一些分辨率:
width:4608 height:3456
width:4608 height:2304
width:3456 height:3456
width:3840 height:2160
width:3280 height:2448
width:3264 height:2448
width:3264 height:1840
width:3264 height:1632
width:2448 height:2448
width:2592 height:1952
width:2048 height:1536
width:1920 height:1080
width:1440 height:1080
width:1536 height:864
width:1456 height:1456
width:1920 height:960
width:1440 height:720
width:1280 height:960
width:1280 height:720
width:960 height:720
参考地址:
[1].官网示例 https://github.com/googlesamples/android-Camera2Basic
[2]. https://blog.csdn.net/z_x_Qiang/article/details/77600880?locationNum=1&fps=1