AndroidのカメラをUIに表示する【Androidアプリ開発】

はじめに
AndroidのカメラをUIに表示するソースコードを解説します。UIは、
Composable
を使って構成します。
ソースコード
AndroidManifest.xml
AndroidManifest.xml
に以下を追加します。
uses-feature
< android:name="android.hardware.camera"
android:required="false" />
uses-permission android:name="android.permission.CAMERA" /> <
build.gradle.kts (Module :app)
モジュールレベルの build.gradle.kts
の
dependencies
に以下を追加して、依存ライブラリをインストールします。
("androidx.camera:camera-camera2:1.3.1")
implementation("androidx.camera:camera-lifecycle:1.3.1")
implementation("androidx.camera:camera-view:1.3.1") implementation
MainActivity
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
{
setContent {
RtmpTestTheme (
Surface= Modifier.fillMaxSize(),
modifier = MaterialTheme.colorScheme.background
color ) {
// CameraPreview() に hasCameraPermission を渡します
()
CameraPreviewWithPermissionRequest}
}
}
}
}
@Composable
fun CameraPreviewWithPermissionRequest() {
var hasCameraPermission by remember { mutableStateOf(false) }
val context = LocalContext.current
// パーミッションのリクエストの結果を受け取る Launcher
val permissionLauncher = rememberLauncherForActivityResult(
= ActivityResultContracts.RequestPermission(),
contract = { isGranted: Boolean ->
onResult = isGranted
hasCameraPermission }
)
// アプリがフォアグラウンドに来たときにパーミッションの状態をチェック
(key1 = true) {
LaunchedEffectif (context.checkSelfPermission(android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
.launch(android.Manifest.permission.CAMERA)
permissionLauncher} else {
= true
hasCameraPermission }
}
if (hasCameraPermission) {
()
CameraPreview} else {
("カメラのアクセス許可が必要です。")
Text}
}
CameraPreview.kt
@Composable
fun CameraPreview() {
val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current
val cameraProviderFuture = remember { ProcessCameraProvider.getInstance(context) }
val previewView = remember { PreviewView(context) } // CameraXライブラリの一部で、カメラのプレビューを表示するためのビュー
val modifier = Modifier.fillMaxSize()
(
AndroidView= modifier,
modifier = { previewView },
factory = { view ->
update val cameraProvider = cameraProviderFuture.get()
val preview = Preview.Builder().build().also {
.setSurfaceProvider(view.surfaceProvider)
it}
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
.unbindAll()
cameraProvider.bindToLifecycle(
cameraProvider, cameraSelector, preview
lifecycleOwner)
} catch(exc: Exception) {
.e("CameraPreview", "Use case binding failed", exc)
Log}
}
)
}
解説
このコードは、AndroidのJetpack
Composeを使用して、カメラのプレビューを表示するためのComposable関数(CameraPreview
)を定義しています。Composable関数は、UIを宣言的に記述するためのもので、Jetpack
Composeで使用されます。この特定の例では、カメラのプレビューを画面に表示するために、CameraXライブラリと一緒に使用されています。
ここで重要なクラスと関数について解説します:
PreviewView
PreviewView
は、CameraXライブラリの一部で、カメラのプレビューを表示するためのビューです。Androidの従来のビューシステムに属しており、Compose内で使用するためには、AndroidView
というComposable関数を介して統合する必要があります。
AndroidView
AndroidView
は、既存のAndroidビュー(この場合はPreviewView
)をComposeに統合するために使用されるComposable関数です。これにより、Composeが中心のアプリケーションでも、まだComposeに移行されていない旧式のビューコンポーネントを使用できるようになります。
コード解説
ローカルコンテキストとライフサイクルオーナーの取得
val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current
Compose内で、現在のコンテキストとライフサイクルオーナーを取得しています。これらはカメラのセットアップとバインディングに必要です。
CameraProviderの取得とPreviewViewのインスタンス化
val cameraProviderFuture = remember { ProcessCameraProvider.getInstance(context) }
val previewView = remember { PreviewView(context) }
remember
を使用して、ProcessCameraProvider
のインスタンス(将来的な結果を含む)とPreviewView
のインスタンスを保持します。これにより、これらのオブジェクトは、Composableが再構築されるたびに再インスタンス化されることはありません。
AndroidViewを使ってPreviewViewをComposeに統合
(
AndroidView= modifier,
modifier = { previewView },
factory = { view ->
update // ...
}
)
AndroidView
Composableは、PreviewView
をComposeのUIツリーに統合します。factory
パラメータにはPreviewView
のインスタンスを渡し、update
ブロックでは、カメラのセットアップとバインディングのロジックを記述します。
カメラのプレビューをセットアップ
val cameraProvider = cameraProviderFuture.get()
val preview = Preview.Builder().build().also {
.setSurfaceProvider(view.surfaceProvider)
it}
cameraProviderFuture.get()
でCameraProviderを取得し、Preview
のインスタンスを作成して、surfaceProvider
を設定します。
カメラセレクターを設定し、ライフサイクルにバインド
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
.unbindAll()
cameraProvider.bindToLifecycle(
cameraProvider, cameraSelector, preview
lifecycleOwner)
} catch(exc: Exception) {
.e("CameraPreview", "Use case binding failed", exc)
Log}
デフォルトのバックカメラを使用するようにカメラセレクターを設定し、cameraProvider
を使って、カメラのプレビューをライフサイクルオーナーにバインドします。これにより、アプリのライフサイクルと同期してカメラのリソースが管理されます。例外が発生した場合は、エラーログを出力します。
全体として、このコードはComposeを使用してカメラのプレビューを表示する一例ですが、実際のアプリではパーミッションの確認など、さらに多くの処理を行う必要があります。また、remember
が使用されているので、これらのインスタンスはComposableが再構築されても保持されます。
関連記事
- ROOMを使わずにSQLiteを扱う、Androidアプリ開発
- 【断酒iOSアプリ制作】Realmでデータの永続化 (9日目)
- iOSアプリ開発でSQLiteを使う FMDB
- Java開発が爆速に!超便利なJShellの使い方