Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions camera/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,14 @@ dependencies {
implementation(libs.androidx.camera.compose)
implementation(libs.androidx.camera.viewfinder.compose)
implementation(libs.androidx.camera.lifecycle)
implementation(libs.androidx.camera.mlkit.vision)
implementation(libs.androidx.camera.camera2)
implementation(libs.androidx.concurrent.futures.ktx)
implementation(libs.androidx.camera.extensions)
implementation(libs.androidx.camera.video)
implementation(libs.androidx.camera.effects)
implementation(libs.androidx.media3.effect)
implementation(libs.mlkit.barcode.scanning)
implementation(libs.mlkit.face.detection)
implementation(libs.androidx.window)
implementation(libs.play.services.wearable)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.camera.snippets.camerax

import android.util.Size
import androidx.activity.ComponentActivity
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.lifecycle.LifecycleOwner
import java.util.concurrent.Executor

private class ImageAnalysisActivity : ComponentActivity() {

@Suppress("DEPRECATION")
private fun bindImageAnalysis(
cameraProvider: ProcessCameraProvider,
cameraSelector: CameraSelector,
preview: Preview,
executor: Executor,
) {
// [START android_camerax_analyze_bind_lifecycle]
val imageAnalysis = ImageAnalysis.Builder()
// enable the following line if RGBA output is needed.
// .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
.setTargetResolution(Size(1280, 720))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
imageAnalysis.setAnalyzer(
executor,
ImageAnalysis.Analyzer { imageProxy ->
val rotationDegrees = imageProxy.imageInfo.rotationDegrees
// Insert your code here
// ...
// after done, release the ImageProxy object.
imageProxy.close()
}
)

cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageAnalysis, preview)
// [END android_camerax_analyze_bind_lifecycle]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/*
* Copyright 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.camera.snippets.camerax

import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraMetadata
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.annotation.RequiresApi
import androidx.camera.camera2.interop.Camera2CameraInfo
import androidx.camera.camera2.interop.Camera2Interop
import androidx.camera.camera2.interop.ExperimentalCamera2Interop
import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.Lifecycle.State
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import com.example.camera.snippets.R

private class ArchitectureActivity : ComponentActivity() {

private fun cameraProviderPreviewSnippet(
cameraProvider: ProcessCameraProvider,
lifecycleOwner: LifecycleOwner,
cameraSelector: CameraSelector,
) {
// [START android_camerax_architecture_preview_provider]
val preview = Preview.Builder().build()
val viewFinder: PreviewView = findViewById(R.id.previewView)

// The use case is bound to an Android Lifecycle with the following code.
val camera = cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)

// PreviewView creates a surface provider and is the recommended provider.
preview.setSurfaceProvider(viewFinder.getSurfaceProvider())
// [END android_camerax_architecture_preview_provider]
}
}

private object CustomLifecycleSnippet {
// [START android_camerax_architecture_custom_lifecycle]
class CustomLifecycle : LifecycleOwner {
private val lifecycleRegistry: LifecycleRegistry

init {
lifecycleRegistry = LifecycleRegistry(this)
lifecycleRegistry.currentState = Lifecycle.State.CREATED
}
// ...
fun doOnResume() {
lifecycleRegistry.currentState = State.RESUMED
}
// ...
override val lifecycle: Lifecycle
get() = lifecycleRegistry
}
// [END android_camerax_architecture_custom_lifecycle]
}

private class ConcurrentUseCasesActivity : ComponentActivity() {
private val previewView: PreviewView by lazy { findViewById(R.id.previewView) }

// [START android_camerax_architecture_concurrent_use_cases]
private lateinit var imageCapture: ImageCapture

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

cameraProviderFuture.addListener(
Runnable {
// Camera provider is now guaranteed to be available.
val cameraProvider = cameraProviderFuture.get()

// Set up the preview use case to display camera preview.
val preview = Preview.Builder().build()

// Set up the capture use case to allow users to take photos.
imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build()

// Choose the camera by requiring a lens facing.
val cameraSelector = CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_FRONT)
.build()

// Attach use cases to the camera with the same lifecycle owner.
val camera = cameraProvider.bindToLifecycle(
this as LifecycleOwner, cameraSelector, preview, imageCapture
)

// Connect the preview use case to the previewView.
preview.setSurfaceProvider(
previewView.getSurfaceProvider()
)
},
ContextCompat.getMainExecutor(this)
)
}
// [END android_camerax_architecture_concurrent_use_cases]
}

// [START android_camerax_architecture_check_level_3]
@androidx.annotation.OptIn(ExperimentalCamera2Interop::class)
fun isBackCameraLevel3Device(cameraProvider: ProcessCameraProvider): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return CameraSelector.DEFAULT_BACK_CAMERA
.filter(cameraProvider.availableCameraInfos)
.firstOrNull()
?.let { Camera2CameraInfo.from(it) }
?.getCameraCharacteristic(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) ==
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3
}
return false
}
// [END android_camerax_architecture_check_level_3]

private class VideoCallStreamActivity : ComponentActivity() {
private var camera: Camera? = null

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@Suppress("DEPRECATION")
@androidx.annotation.OptIn(ExperimentalCamera2Interop::class)
private fun bindVideoCallPreview(
cameraProvider: ProcessCameraProvider,
screenAspectRatio: Int,
rotation: Int,
) {
// [START android_camerax_architecture_video_call_stream]
// Set underlying Camera2 stream use case to optimize for video calls.

val videoCallStreamId =
CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL.toLong()

// Check available CameraInfos to find the first one that supports
// the video call stream use case.
val frontCameraInfo = cameraProvider.availableCameraInfos
.first { cameraInfo ->
val isVideoCallStreamingSupported = Camera2CameraInfo.from(cameraInfo)
.getCameraCharacteristic(
CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES
)?.contains(videoCallStreamId)
val isFrontFacing = (
cameraInfo.getLensFacing() ==
CameraSelector.LENS_FACING_FRONT
)
(isVideoCallStreamingSupported == true) && isFrontFacing
}

val cameraSelector = frontCameraInfo.cameraSelector

// Start with a Preview Builder.
val previewBuilder = Preview.Builder()
.setTargetAspectRatio(screenAspectRatio)
.setTargetRotation(rotation)

// Use Camera2Interop.Extender to set the video call stream use case.
Camera2Interop.Extender(previewBuilder).setStreamUseCase(videoCallStreamId)

// Bind the Preview UseCase and the corresponding CameraSelector.
val preview = previewBuilder.build()
camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview)
// [END android_camerax_architecture_video_call_stream]
}
}
Loading
Loading