# Android CameraX nel 2026: Cattura Foto e Video con Domande per Colloqui > Tutorial CameraX per sviluppatori Android: gestione del lifecycle, cattura foto e video con Jetpack Compose e domande tecniche per colloqui. - Published: 2026-09-11 - Updated: 2026-09-11 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- Android CameraX semplifica lo sviluppo della fotocamera astraendo la complessità hardware dietro un'API lifecycle-aware. Con la versione 1.6.2 ora stabile e la migrazione a CameraPipe completata, CameraX offre lo stesso stack camera ad alte prestazioni che alimenta l'app fotocamera Pixel. > **Novità di CameraX 1.6** > > CameraX 1.6 è migrato a CameraPipe, utilizza Media3 Muxer come default per VideoCapture e ha stabilizzato l'API SessionConfig. I builder DSL Kotlin (`preview { }`, `imageCapture { }`, `videoCapture { }`) riducono il boilerplate del 40%. ## Architettura CameraX e Modello Use Case CameraX fornisce quattro use case primari che possono essere eseguiti contemporaneamente: Preview, ImageCapture, ImageAnalysis e VideoCapture. Ogni use case si lega a un [LifecycleOwner](https://developer.android.com/topic/libraries/architecture/lifecycle), così la fotocamera si avvia e si ferma automaticamente con l'activity o il fragment. Il CameraProvider agisce come factory che istanzia questi use case e li lega alla fotocamera. Questo disaccoppiamento significa che lo stesso codice funziona su dispositivi di diversi OEM senza preoccuparsi delle peculiarità specifiche del produttore. ```kotlin // CameraSetup.kt class CameraSetup( private val context: Context, private val lifecycleOwner: LifecycleOwner ) { private lateinit var cameraProvider: ProcessCameraProvider private var imageCapture: ImageCapture? = null private var videoCapture: VideoCapture? = null suspend fun initialize() { // ProcessCameraProvider lega gli use case al lifecycle cameraProvider = ProcessCameraProvider.getInstance(context).await() } fun bindUseCases(previewView: PreviewView) { // Slegare gli use case esistenti prima di rilegarli cameraProvider.unbindAll() // Use case Preview mostra il feed della fotocamera val preview = Preview.Builder() .build() .apply { setSurfaceProvider(previewView.surfaceProvider) } // ImageCapture per le foto imageCapture = ImageCapture.Builder() .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY) .build() // VideoCapture con Recorder val recorder = Recorder.Builder() .setQualitySelector(QualitySelector.from(Quality.FHD)) .build() videoCapture = VideoCapture.withOutput(recorder) // Legare tutti gli use case al lifecycle cameraProvider.bindToLifecycle( lifecycleOwner, CameraSelector.DEFAULT_BACK_CAMERA, preview, imageCapture, videoCapture ) } } ``` La chiamata `bindToLifecycle` connette gli use case sia all'hardware della fotocamera che al lifecycle. Quando il LifecycleOwner entra nello stato STARTED, la fotocamera si apre. Quando entra in STOPPED, si chiude automaticamente. ## Implementazione della Cattura Foto con ImageCapture ImageCapture fornisce due modalità di cattura: `CAPTURE_MODE_MINIMIZE_LATENCY` per una risposta rapida dello scatto e `CAPTURE_MODE_MAXIMIZE_QUALITY` per scatti ad elaborazione intensiva. La scelta dipende se l'app dà priorità alla velocità (app social) o alla qualità (scanner di documenti). ```kotlin // PhotoCaptureManager.kt class PhotoCaptureManager( private val context: Context, private val imageCapture: ImageCapture ) { private val mainExecutor = ContextCompat.getMainExecutor(context) fun capturePhoto(onResult: (Uri?) -> Unit) { // Generare nome file univoco con timestamp val filename = "IMG_${System.currentTimeMillis()}.jpg" val contentValues = ContentValues().apply { put(MediaStore.MediaColumns.DISPLAY_NAME, filename) put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg") // Salvare nella cartella Pictures/CameraX su Android 10+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/CameraX") } } val outputOptions = ImageCapture.OutputFileOptions.Builder( context.contentResolver, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues ).build() imageCapture.takePicture( outputOptions, mainExecutor, object : ImageCapture.OnImageSavedCallback { override fun onImageSaved(results: ImageCapture.OutputFileResults) { // results.savedUri contiene l'URI MediaStore onResult(results.savedUri) } override fun onError(exception: ImageCaptureException) { Log.e("PhotoCapture", "Cattura fallita: ${exception.message}") onResult(null) } } ) } } ``` CameraX 1.5 ha aggiunto il supporto per la cattura DNG (RAW) per le app che necessitano di dati grezzi dal sensore. Verificare le capacità del dispositivo con `ImageCapture.getImageCaptureCapabilities()` prima di abilitare l'output RAW. ## Registrazione Video con VideoCapture e Recorder VideoCapture utilizza un oggetto [Recorder](https://developer.android.com/reference/androidx/camera/video/Recorder) per gestire encoding e muxing. L'API Recorder segue un pattern prepare-start-stop che gestisce la sincronizzazione audio automaticamente. ```kotlin // VideoRecordingManager.kt class VideoRecordingManager( private val context: Context, private val videoCapture: VideoCapture ) { private var activeRecording: Recording? = null fun startRecording(onEvent: (VideoRecordEvent) -> Unit): Boolean { // Verificare se è già in registrazione if (activeRecording != null) return false val filename = "VID_${System.currentTimeMillis()}.mp4" val contentValues = ContentValues().apply { put(MediaStore.MediaColumns.DISPLAY_NAME, filename) put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4") if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/CameraX") } } val mediaStoreOutput = MediaStoreOutputOptions.Builder( context.contentResolver, MediaStore.Video.Media.EXTERNAL_CONTENT_URI ) .setContentValues(contentValues) .build() // Preparare la registrazione con audio se il permesso è concesso val pendingRecording = videoCapture.output .prepareRecording(context, mediaStoreOutput) if (hasAudioPermission()) { pendingRecording.withAudioEnabled() } // Avviare la registrazione e salvare il riferimento activeRecording = pendingRecording.start( ContextCompat.getMainExecutor(context) ) { event -> onEvent(event) // Cancellare il riferimento quando la registrazione è completata if (event is VideoRecordEvent.Finalize) { activeRecording = null } } return true } fun stopRecording() { activeRecording?.stop() } fun pauseRecording() { activeRecording?.pause() } fun resumeRecording() { activeRecording?.resume() } private fun hasAudioPermission(): Boolean { return ContextCompat.checkSelfPermission( context, Manifest.permission.RECORD_AUDIO ) == PackageManager.PERMISSION_GRANTED } } ``` CameraX 1.5 ha aggiunto il supporto per video slow-motion. Interrogare le capacità con `Recorder.getHighSpeedVideoCapabilities()` prima di abilitare la registrazione a 120fps o 240fps. ## CameraX con Jetpack Compose CameraX 1.5 ha introdotto l'artifact `camera-compose` con un composable `CameraXViewfinder`. Per le app che utilizzano ancora PreviewView basato su View, AndroidView fornisce l'interoperabilità. ```kotlin // CameraPreviewComposable.kt @Composable fun CameraPreview( modifier: Modifier = Modifier, onPreviewViewCreated: (PreviewView) -> Unit ) { AndroidView( modifier = modifier.fillMaxSize(), factory = { context -> PreviewView(context).apply { implementationMode = PreviewView.ImplementationMode.COMPATIBLE scaleType = PreviewView.ScaleType.FILL_CENTER onPreviewViewCreated(this) } } ) } @Composable fun CameraScreen(viewModel: CameraViewModel = viewModel()) { val context = LocalContext.current val lifecycleOwner = LocalLifecycleOwner.current LaunchedEffect(Unit) { viewModel.initializeCamera(context, lifecycleOwner) } Box(modifier = Modifier.fillMaxSize()) { CameraPreview( onPreviewViewCreated = { previewView -> viewModel.bindPreview(previewView) } ) // Overlay pulsanti di cattura Row( modifier = Modifier .align(Alignment.BottomCenter) .padding(32.dp), horizontalArrangement = Arrangement.spacedBy(24.dp) ) { IconButton( onClick = { viewModel.capturePhoto() } ) { Icon(Icons.Default.Camera, "Scatta foto") } IconButton( onClick = { viewModel.toggleRecording() } ) { Icon( if (viewModel.isRecording) Icons.Default.Stop else Icons.Default.Videocam, "Registra video" ) } } } } ``` Per implementazioni Compose-first, la guida alle [domande per colloqui Jetpack Compose](/technologies/android/interview-questions/android-compose) tratta pattern di integrazione ViewModel che si applicano direttamente alla gestione dello stato della fotocamera. ## Gestione dei Permessi della Fotocamera Android richiede il permesso CAMERA a runtime. RECORD_AUDIO è necessario solo quando si registra video con audio. Il flusso dei permessi dovrebbe spiegare perché l'accesso è necessario prima di richiederlo. ```kotlin // PermissionHandler.kt class CameraPermissionHandler(private val activity: ComponentActivity) { private val requiredPermissions = arrayOf( Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO ) private val permissionLauncher = activity.registerForActivityResult( ActivityResultContracts.RequestMultiplePermissions() ) { permissions -> val cameraGranted = permissions[Manifest.permission.CAMERA] == true val audioGranted = permissions[Manifest.permission.RECORD_AUDIO] == true if (cameraGranted) { onCameraPermissionGranted(audioGranted) } else { onCameraPermissionDenied() } } fun checkAndRequestPermissions() { when { hasAllPermissions() -> onCameraPermissionGranted(hasAudioPermission()) shouldShowRationale() -> showPermissionRationale() else -> permissionLauncher.launch(requiredPermissions) } } private fun hasAllPermissions(): Boolean { return requiredPermissions.all { permission -> ContextCompat.checkSelfPermission( activity, permission ) == PackageManager.PERMISSION_GRANTED } } private fun hasAudioPermission(): Boolean { return ContextCompat.checkSelfPermission( activity, Manifest.permission.RECORD_AUDIO ) == PackageManager.PERMISSION_GRANTED } private fun shouldShowRationale(): Boolean { return requiredPermissions.any { permission -> ActivityCompat.shouldShowRequestPermissionRationale(activity, permission) } } } ``` ## Domande per Colloqui su CameraX CameraX appare nei colloqui Android quando si discute di integrazione della fotocamera, gestione del lifecycle o astrazione hardware. Queste domande testano la comprensione dell'architettura e i dettagli pratici di implementazione. ### Perché usare CameraX invece di Camera2? CameraX astrae le peculiarità specifiche del dispositivo che Camera2 espone direttamente. Un'implementazione Camera2 richiede la gestione di centinaia di workaround specifici per dispositivo. CameraX incorpora queste correzioni nella libreria, testata contro il [CameraX Test Lab](https://android-developers.googleblog.com/2025/11/introducing-camerax-15-powerful-video.html) che copre oltre 150 modelli di dispositivi. Il binding lifecycle-aware elimina la gestione manuale delle risorse. Camera2 richiede chiamate esplicite open/close che causano leak se non gestite correttamente in ogni callback del lifecycle. ### Come lega CameraProvider gli use case al lifecycle? CameraProvider utilizza internamente il pattern LifecycleObserver. Quando si chiama `bindToLifecycle()`, registra un observer sul LifecycleOwner fornito. Questo observer riceve eventi ON_START e ON_STOP per aprire e chiudere la fotocamera. L'insight chiave: CameraX non avvia la fotocamera immediatamente al bind. Aspetta che il lifecycle raggiunga lo stato STARTED, che corrisponde al timing di Activity.onStart(). ### Cosa succede quando si legano use case incompatibili? Non tutte le combinazioni di use case funzionano su tutti i dispositivi. Preview + VideoCapture + ImageAnalysis + ImageCapture potrebbe fallire su hardware più datato. CameraX lancia una IllegalArgumentException al momento del bind, non a runtime. La soluzione è verificare `CameraProvider.hasCamera()` e le capacità del dispositivo prima di legare combinazioni complesse. Per app critiche, testare esplicitamente su dispositivi di fascia bassa. ### Spiegare la differenza tra CAPTURE_MODE_MINIMIZE_LATENCY e CAPTURE_MODE_MAXIMIZE_QUALITY MINIMIZE_LATENCY riduce il ritardo dello scatto usando pipeline di elaborazione più veloci, possibilmente saltando qualche post-elaborazione. MAXIMIZE_QUALITY applica l'elaborazione HDR+ completa, riduzione del rumore e cattura multi-frame su dispositivi supportati. Il compromesso: la modalità latency cattura in 100-200ms, la modalità quality può richiedere 500ms-1s a seconda dell'illuminazione. Le app social tipicamente scelgono latency. Le app scanner documenti scelgono quality. ### Come gestisce CameraX la rotazione del dispositivo? CameraX gestisce la rotazione automaticamente attraverso l'impostazione target rotation. Di default, usa la rotazione del Display, ma le app possono sovrascriverla con `setTargetRotation()`. I dati EXIF dell'immagine di output contengono il tag di orientamento corretto. Per PreviewView, lo scaleType gestisce le differenze di aspect ratio. FILL_CENTER ritaglia per riempire, FIT_CENTER mostra il letterboxing. La scelta dipende se l'app dà priorità all'anteprima a schermo intero o all'evitare il ritaglio. ## Dipendenze e Setup per CameraX 1.6 La libreria CameraX è divisa in più artifact. Includere solo ciò che l'app utilizza per minimizzare la dimensione dell'APK. ```kotlin // build.gradle.kts (Module: app) dependencies { val cameraxVersion = "1.6.2" // Libreria core richiesta per tutti gli use case implementation("androidx.camera:camera-core:$cameraxVersion") // Implementazione Camera2 (richiesta) implementation("androidx.camera:camera-camera2:$cameraxVersion") // Integrazione lifecycle implementation("androidx.camera:camera-lifecycle:$cameraxVersion") // Use case VideoCapture implementation("androidx.camera:camera-video:$cameraxVersion") // PreviewView e componenti UI fotocamera implementation("androidx.camera:camera-view:$cameraxVersion") // Opzionale: Extensions (Night mode, HDR, ecc.) implementation("androidx.camera:camera-extensions:$cameraxVersion") // Opzionale: Effetti in tempo reale implementation("androidx.camera:camera-effects:$cameraxVersion") } android { // CameraX richiede bytecode Java 11 compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } } ``` Il Manifest necessita di dichiarazioni feature e permessi: ```xml ``` I pattern correlati per [Kotlin Coroutines](/blog/android/mastering-kotlin-coroutines) si applicano quando si wrappano le chiamate ListenableFuture di CameraX in funzioni suspend. ## Cosa Cambia CameraX 1.6 per le App in Produzione CameraX 1.6 ha portato tre cambiamenti che influenzano le implementazioni esistenti: 1. **Backend CameraPipe**: Lo stack camera interno ora usa CameraPipe, la stessa architettura della fotocamera Pixel. Questo migliora le prestazioni sui dispositivi Pixel e fornisce una base più pulita per funzionalità avanzate. Il codice esistente non necessita di modifiche. 2. **Media3 Muxer default**: VideoCapture ora usa Media3 Muxer invece di MediaMuxer. Questo migliora la resilienza ai crash: se l'app termina durante la registrazione, il file video rimane riproducibile. La superficie API è invariata. 3. **API SessionConfig stabile**: Le app possono ora configurare impostazioni avanzate della fotocamera attraverso SessionConfig senza annotazioni sperimentali. Questo abilita funzionalità come l'uso simultaneo di fotocamera anteriore e posteriore su dispositivi supportati. **Percorso di migrazione**: Aggiornare la versione della dipendenza. Testare sui dispositivi che precedentemente avevano problemi. Le [note di rilascio CameraX](https://developer.android.com/jetpack/androidx/releases/camera) documentano eventuali cambiamenti comportamentali tra le versioni. - CameraX usa il binding lifecycle-aware: `bindToLifecycle()` connette gli use case sia alla fotocamera che al lifecycle dell'Activity - Le modalità ImageCapture scambiano latenza per qualità: scegliere in base allo use case, non alle capacità del dispositivo - VideoCapture richiede il setup del Recorder prima del binding: preparare le opzioni di output prima di iniziare - La gestione dei permessi dovrebbe spiegare lo scopo prima della richiesta: riduce i tassi di rifiuto - CameraX 1.6 è migrato internamente a CameraPipe: nessuna modifica API richiesta, ma testare sui dispositivi target - Le domande dei colloqui si concentrano sulla gestione del lifecycle, combinazioni di use case e confronto con Camera2 --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/it/blog/android/camerax-photo-video-capture-interview-questions