Android Camera2 之 CameraManager 詳解
一、簡介
CameraManager
是系統服務之一,專門用於 檢測 和 開啟相機,以及 獲取相機裝置特性。
官方文件其實說的蠻清楚的了,英文好的同學也可以直接看官方文件把:https://developer.android.google.cn/reference/android/hardware/camera2/CameraManager
二、獲取 CameraManager 例項
通過 Context
類的 getSystemService()
方法來獲取一個系統服務,引數使用 Context.CAMERA_SERVICE
或 CameraManager.class
都行。
// 方式一
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
// 方式二
CameraManager manager = (CameraManager) context.getSystemService(CameraManager.class);
三、內部類
CameraManager 中包含兩個公有的內部類,分別為:
1. CameraManager.AvailabilityCallback
當一個相機裝置的可用狀態發生變化時,就會回撥這個類的 onCameraAvailable(String cameraId)
onCameraUnavailable(String cameraId)
方法。
2. CameraManager.TorchCallback
當一個相機裝置的閃光燈的 Torch 模式可用狀態發生變化時,就會回撥這個類的 onTorchModeChanged(String cameraId, boolean enabled)
和 onTorchModeUnavailable(String cameraId)
方法。
通過 setTorchMode(String cameraId, boolean enabled)
方法設定 Torch 模式。
四、常用方法
其中第二條和第三條是重點的重點,一定要掌握的。
1. String[] getCameraIdList()
獲取當前連線的相機裝置列表,這個 id 通常都是從 0
開始並依次遞增的。
對於一般的手機而言,後置攝像頭一般為 “0”,常量值為 CameraCharacteristics.LENS_FACING_FRONT
;
前置攝像頭一般為 “1”,常量值為 CameraCharacteristics.LENS_FACING_BACK
。
2. CameraCharacteristics getCameraCharacteristics(String cameraId)
根據 cameraId 獲取對應相機裝置的特徵。返回一個 CameraCharacteristics
,類比於舊 API 中的 Camera.Parameter
類,裡面封裝了相機裝置固有的所有屬性功能。
3. void openCamera(String cameraId, final CameraDevice.StateCallback callback, Handler handler)
開啟指定的相機裝置,該方法使用當前程序 uid 繼續呼叫 openCameraForUid(cameraId, callback, handler, USE_CALLING_UID)
方法。
引數解釋:
- cameraId : 需要開啟的相機 id。
- callback : 回撥類,常用如下幾個回撥方法。
- onOpened(CameraDevice camera) 成功開啟時的回撥,此時 camera 就準備就緒,並且可以得到一個
CameraDevice
例項。 - onDisconnected(CameraDevice camera) 當 camera 不再可用或開啟失敗時的回撥,通常在該方法中進行資源釋放的操作。
- onError(CameraDevice camera, int error) 當 camera 開啟失敗時的回撥,error 為具體錯誤原因,定義在
CameraDevice.StateCallback
類中。通常在該方法中也要進行資源釋放的操作。
- onOpened(CameraDevice camera) 成功開啟時的回撥,此時 camera 就準備就緒,並且可以得到一個
- handler : 指定回撥執行的執行緒。傳 null 時預設使用當前執行緒的 Looper,我們通常建立一個後臺執行緒來處理。
使用示例:
private int mCameraId = CameraCharacteristics.LENS_FACING_FRONT;
private CameraManager mCameraManager; // 相機管理者
private CameraDevice mCameraDevice; // 相機物件
private Handler mBackgroundHandler;
private HandlerThread mBackgroundThread;
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
mCameraDevice = camera;
// 當相機成功開啟時回撥該方法,接下來可以執行建立預覽的操作
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
// 當相機斷開連線時回撥該方法,應該在此執行釋放相機的操作
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
// 當相機開啟失敗時,應該在此執行釋放相機的操作
}
};
public void openCamera() {
try {
// 前處理
mCameraManager.openCamera(Integer.toString(mCameraId), mStateCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
後臺執行緒建立示例:
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread("CameraBackground");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
private void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
4. void registerAvailabilityCallback(AvailabilityCallback callback, Handler handler)
註冊一個 AvailabilityCallback
回撥,handle 指定處理回撥的執行緒,傳 null 時預設使用當前執行緒的 Looper。
CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
cameraManager.registerAvailabilityCallback(new CameraManager.AvailabilityCallback() {
@Override
public void onCameraAvailable(@NonNull String cameraId) {
super.onCameraAvailable(cameraId);
}
@Override
public void onCameraUnavailable(@NonNull String cameraId) {
super.onCameraUnavailable(cameraId);
}
}, mBackgroundHandler);
5. void unregisterAvailabilityCallback(AvailabilityCallback callback)
登出 AvailabilityCallback
回撥,當回撥不再需要時一定要登出,否則將帶來記憶體洩漏的問題。
6. void registerTorchCallback(TorchCallback callback, Handler handler)
註冊一個 TorchCallback
回撥,handle 解釋如上。
CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
cameraManager.registerTorchCallback(new CameraManager.TorchCallback() {
@Override
public void onTorchModeUnavailable(@NonNull String cameraId) {
super.onTorchModeUnavailable(cameraId);
}
@Override
public void onTorchModeChanged(@NonNull String cameraId, boolean enabled) {
super.onTorchModeChanged(cameraId, enabled);
}
}, mBackgroundHandler);
7. void unregisterTorchCallback(TorchCallback callback)
登出 TorchCallback
回撥,當回撥不再需要時一定要登出,否則將帶來記憶體洩漏的問題。
8. void setTorchMode(String cameraId, boolean enabled)
開啟和關閉指定相機裝置的閃光燈功能。