第7章:カメラを開く
デバイス上のすべてのカメラを列挙し(第6章)、使用したいカメラを特定しました。通常は、最もハードウェアレベルの高い背面カメラを選択します。次のステップは、そのカメラを開くことです。カメラハードウェアへのアクティブな低レベル接続を確立し、キャプチャセッションを構成してリクエストを送信できるようにします。カメラを開くことは、アプリがカメラメタデータの受動的な観察者から、実際のハードウェアのアクティブな制御者へと移行する重要なステップです。
プロダクション品質のカメラオープン/クローズのライフサイクルコードを確認したい場合は、Android Camera Parameters アプリの GitHub リポジトリ を参照してください。その Camera2Controller クラスには、エラー回復、リトライロジック、クリーンアップなど、実機での運用に耐えうるライフサイクル管理が実装されています。
CameraDevice とは何か?
CameraDevice は、デバイス上の特定の物理(または論理)カメラへのアクティブな接続を表すクラスです。カメラを開く前は特性を読み取ることしかできませんが、開いた後は以下のことが可能になります:
CameraCaptureSessionの作成(第8章)CaptureRequestの送信(第8・9章)- フレームごとの
CaptureResultメタデータの読み取り - デバイスのクローズ
主要なプロパティ
- 単一ユーザーリソース: 特定のカメラを一度に開けるのは 1 つのアプリ(厳密には 1 つの
CameraDeviceインスタンス)だけです。優先度の高いアプリ(電話の着信など)がカメラを必要とした場合、あなたのアプリは強制的に切断されます。 - 厳格なコールバック駆動型ライフサイクル: コンストラクタで作成することはできません。
CameraManager.openCamera()を呼び出し、StateCallbackを介して非同期にインスタンスを受け取ります。
StateCallback:CameraDevice のライフサイクルマシン
CameraDevice.StateCallback は、必ず実装しなければならない 3 つのメソッドを持つ抽象クラスです。
| メソッド | 呼ばれるタイミング | すべきこと |
|---|---|---|
onOpened(camera) | カメラのオープンに成功し、使用可能になった。 | camera 参照をプロパティに保存する。セッションの作成(第8章)へ進む。 |
onDisconnected(camera) | 他のアプリにカメラを奪われた、または無効化された。 | 直ちに camera.close() を呼び出し、参照を null にする。 |
onError(camera, error) | オープン中または動作中に致命的なエラーが発生した。 | camera.close() を呼び出し、エラー内容に応じてユーザーに通知またはリトライする。 |
エラーコード
onError で渡される整数値は、ERROR_CAMERA_IN_USE(使用中)や ERROR_MAX_CAMERAS_IN_USE(同時オープン制限超過)など、原因を特定するためのヒントになります。
Activity のライフサイクルとの統合
カメラは電力を大量に消費する共有リソースであるため、Activity の onResume で開き、onPause で閉じるのが鉄則です。
開くタイミング (onResume)
- 権限がまだ有効か確認する。
- 背景スレッド(第5章)を開始した後に
openCamera()を呼び出す。
閉じるタイミング (onPause)
- 実行中の繰り返しリクエストを停止する。
- キャプチャセッションを閉じる。
CameraDeviceを閉じる。- その後に背景スレッドを停止する。
順番を間違えると、クリーンアップ用のコールバックが実行されるスレッドがなくなり、デッドロックやクラッシュの原因となります。
Semaphore による並行制御
ユーザーがアプリを素早く切り替えた場合などに、前のオープン処理が終わる前に次の openCamera() が呼ばれてしまう「競合状態」が発生することがあります。これを防ぐために、許可証を 1 つだけ持つ Semaphore を使用して、一度に 1 つのオープン/クローズ操作しか行われないように制御します。
まとめ
この章では、カメラハードウェアに接続し、CameraDevice オブジェクトを保持するための重要な手順を学びました。
openCamera(): 非同期でカメラを開く。StateCallback: オープン成功、切断、エラーの各状態をハンドルする。- ライフサイクル管理:
onResume/onPauseに合わせた適切なオープン・クローズの手順。 - Semaphore: 並行操作による競合やクラッシュを防ぐためのロック機構。
これらは Camera2 アプリのバックボーンとなる部分です。このパターンをマスターすれば、Camera2 の運用において最も難しい部分は越えたと言えるでしょう。
次のステップ
CameraDevice を開くことができましたが、まだ「カメラが見ているもの」を画面に表示することはできません。第8章:カメラプレビューの表示では、TextureView を使用して、カメラからのフレームをリアルタイムでレンダリングする方法を学びます。