# Android CameraX em 2026: Captura de Fotos e Vídeos com Perguntas de Entrevista > Guia completo do CameraX 1.6 para Android: arquitetura lifecycle-aware, captura de fotos, gravação de vídeo, integração com Jetpack Compose e perguntas de entrevista técnica. - Published: 2026-09-11 - Updated: 2026-09-11 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- O CameraX simplifica o desenvolvimento de câmeras no Android ao abstrair a complexidade do hardware por trás de uma API lifecycle-aware. Com a versão 1.6.2 agora estável e a migração para o CameraPipe concluída, o CameraX oferece a mesma stack de câmera de alto desempenho que alimenta o aplicativo de câmera do Pixel. > **Mudanças Principais no CameraX 1.6** > > O CameraX 1.6 migrou para o CameraPipe, usa o Media3 Muxer por padrão para VideoCapture e estabilizou a API SessionConfig. Os builders DSL do Kotlin (`preview { }`, `imageCapture { }`, `videoCapture { }`) reduzem o boilerplate em 40%. ## Arquitetura do CameraX e Modelo de Casos de Uso O CameraX fornece quatro casos de uso principais que podem ser executados simultaneamente: Preview, ImageCapture, ImageAnalysis e VideoCapture. Cada caso de uso se vincula a um [LifecycleOwner](https://developer.android.com/topic/libraries/architecture/lifecycle), de modo que a câmera inicia e para automaticamente com a activity ou fragment. O CameraProvider atua como uma factory que instancia esses casos de uso e os vincula à câmera. Esse desacoplamento significa que o mesmo código funciona em dispositivos de diferentes fabricantes sem se preocupar com particularidades específicas de cada OEM. ```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 vincula casos de uso ao lifecycle cameraProvider = ProcessCameraProvider.getInstance(context).await() } fun bindUseCases(previewView: PreviewView) { // Desvincular casos de uso existentes antes de revincular cameraProvider.unbindAll() // Caso de uso Preview exibe o feed da câmera val preview = Preview.Builder() .build() .apply { setSurfaceProvider(previewView.surfaceProvider) } // ImageCapture para fotos imageCapture = ImageCapture.Builder() .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY) .build() // VideoCapture com Recorder val recorder = Recorder.Builder() .setQualitySelector(QualitySelector.from(Quality.FHD)) .build() videoCapture = VideoCapture.withOutput(recorder) // Vincular todos os casos de uso ao lifecycle cameraProvider.bindToLifecycle( lifecycleOwner, CameraSelector.DEFAULT_BACK_CAMERA, preview, imageCapture, videoCapture ) } } ``` A chamada `bindToLifecycle` conecta os casos de uso tanto ao hardware da câmera quanto ao lifecycle. Quando o LifecycleOwner entra no estado STARTED, a câmera abre. Quando entra no estado STOPPED, a câmera fecha automaticamente. ## Implementando Captura de Fotos com ImageCapture O ImageCapture fornece dois modos de captura: `CAPTURE_MODE_MINIMIZE_LATENCY` para resposta rápida do obturador, e `CAPTURE_MODE_MAXIMIZE_QUALITY` para fotos que exigem processamento intensivo. A escolha depende de se o aplicativo prioriza velocidade (apps sociais) ou qualidade (scanners de documentos). ```kotlin // PhotoCaptureManager.kt class PhotoCaptureManager( private val context: Context, private val imageCapture: ImageCapture ) { private val mainExecutor = ContextCompat.getMainExecutor(context) fun capturePhoto(onResult: (Uri?) -> Unit) { // Gerar nome de arquivo único com timestamp val filename = "IMG_${System.currentTimeMillis()}.jpg" val contentValues = ContentValues().apply { put(MediaStore.MediaColumns.DISPLAY_NAME, filename) put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg") // Armazenar em Pictures/CameraX no 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 contém a URI do MediaStore onResult(results.savedUri) } override fun onError(exception: ImageCaptureException) { Log.e("PhotoCapture", "Captura falhou: ${exception.message}") onResult(null) } } ) } } ``` O CameraX 1.5 adicionou suporte à captura DNG (RAW) para aplicativos que precisam de dados não processados do sensor. Deve-se verificar a capacidade do dispositivo com `ImageCapture.getImageCaptureCapabilities()` antes de habilitar a saída RAW. ## Gravação de Vídeo com VideoCapture e Recorder O VideoCapture usa um objeto [Recorder](https://developer.android.com/reference/androidx/camera/video/Recorder) para lidar com codificação e muxing. A API Recorder segue um padrão prepare-start-stop que gerencia automaticamente a sincronização de áudio. ```kotlin // VideoRecordingManager.kt class VideoRecordingManager( private val context: Context, private val videoCapture: VideoCapture ) { private var activeRecording: Recording? = null fun startRecording(onEvent: (VideoRecordEvent) -> Unit): Boolean { // Verificar se já está gravando 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() // Preparar gravação com áudio se tiver permissão val pendingRecording = videoCapture.output .prepareRecording(context, mediaStoreOutput) if (hasAudioPermission()) { pendingRecording.withAudioEnabled() } // Iniciar gravação e armazenar referência activeRecording = pendingRecording.start( ContextCompat.getMainExecutor(context) ) { event -> onEvent(event) // Limpar referência quando a gravação terminar 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 } } ``` O CameraX 1.5 adicionou suporte a vídeo em câmera lenta. As capacidades podem ser consultadas com `Recorder.getHighSpeedVideoCapabilities()` antes de habilitar gravação em 120fps ou 240fps. ## CameraX com Jetpack Compose O CameraX 1.5 introduziu o artifact `camera-compose` com um composable `CameraXViewfinder`. Para aplicativos que ainda usam PreviewView baseado em View, o AndroidView fornece interoperabilidade. ```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) } ) // Botões de captura em overlay Row( modifier = Modifier .align(Alignment.BottomCenter) .padding(32.dp), horizontalArrangement = Arrangement.spacedBy(24.dp) ) { IconButton( onClick = { viewModel.capturePhoto() } ) { Icon(Icons.Default.Camera, "Tirar foto") } IconButton( onClick = { viewModel.toggleRecording() } ) { Icon( if (viewModel.isRecording) Icons.Default.Stop else Icons.Default.Videocam, "Gravar vídeo" ) } } } } ``` Para implementações Compose-first, o guia de [perguntas de entrevista sobre Jetpack Compose](/technologies/android/interview-questions/android-compose) cobre padrões de integração com ViewModel que se aplicam diretamente ao gerenciamento de estado da câmera. ## Tratamento de Permissões da Câmera O Android requer a permissão CAMERA em tempo de execução. RECORD_AUDIO só é necessária ao gravar vídeo com som. O fluxo de permissões deve explicar por que o acesso é necessário antes de solicitá-lo. ```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) } } } ``` ## Perguntas de Entrevista sobre CameraX O CameraX aparece em entrevistas de Android quando se discute integração de câmera, gerenciamento de lifecycle ou abstração de hardware. Essas perguntas testam a compreensão da arquitetura e detalhes práticos de implementação. ### Por que usar CameraX em vez de Camera2? O CameraX abstrai as particularidades específicas de dispositivos que o Camera2 expõe diretamente. Uma implementação de Camera2 requer lidar com centenas de soluções alternativas específicas para cada dispositivo. O CameraX incorpora essas correções na biblioteca, testadas contra o [CameraX Test Lab](https://android-developers.googleblog.com/2025/11/introducing-camerax-15-powerful-video.html) que cobre mais de 150 modelos de dispositivos. A vinculação lifecycle-aware elimina o gerenciamento manual de recursos. O Camera2 requer chamadas explícitas de open/close que causam vazamentos de memória se não forem tratadas corretamente em cada callback do lifecycle. ### Como o CameraProvider vincula casos de uso ao lifecycle? O CameraProvider usa o padrão LifecycleObserver internamente. Ao chamar `bindToLifecycle()`, ele registra um observador no LifecycleOwner fornecido. Esse observador recebe eventos ON_START e ON_STOP para abrir e fechar a câmera. O ponto-chave: o CameraX não inicia a câmera imediatamente ao vincular. Ele aguarda o lifecycle atingir o estado STARTED, que corresponde ao timing de Activity.onStart(). ### O que acontece ao vincular casos de uso incompatíveis? Nem todas as combinações de casos de uso funcionam em todos os dispositivos. Preview + VideoCapture + ImageAnalysis + ImageCapture pode falhar em hardware antigo. O CameraX lança uma IllegalArgumentException no momento da vinculação, não em tempo de execução. A solução é verificar `CameraProvider.hasCamera()` e as capacidades do dispositivo antes de vincular combinações complexas. Para aplicativos críticos, testar explicitamente em dispositivos de entrada. ### Explicar a diferença entre CAPTURE_MODE_MINIMIZE_LATENCY e CAPTURE_MODE_MAXIMIZE_QUALITY MINIMIZE_LATENCY reduz o lag do obturador usando pipelines de processamento mais rápidos, possivelmente pulando alguns pós-processamentos. MAXIMIZE_QUALITY aplica processamento completo de HDR+, redução de ruído e captura multi-frame em dispositivos compatíveis. O trade-off: o modo latência captura em 100-200ms, o modo qualidade pode levar 500ms-1s dependendo da iluminação. Apps sociais tipicamente escolhem latência. Apps de scanner de documentos escolhem qualidade. ### Como o CameraX lida com a rotação do dispositivo? O CameraX lida automaticamente com a rotação através da configuração de target rotation. Por padrão, ele usa a rotação do Display, mas os apps podem sobrescrever com `setTargetRotation()`. Os dados EXIF da imagem de saída contêm a tag de orientação correta. Para PreviewView, o scaleType lida com diferenças de proporção. FILL_CENTER corta para preencher, FIT_CENTER mostra letterboxing. A escolha depende de se o app prioriza visualização em tela cheia ou evitar cortes. ## Dependências e Configuração para CameraX 1.6 A biblioteca CameraX é dividida em múltiplos artifacts. Incluir apenas o que o app usa para minimizar o tamanho do APK. ```kotlin // build.gradle.kts (Module: app) dependencies { val cameraxVersion = "1.6.2" // Biblioteca core necessária para todos os casos de uso implementation("androidx.camera:camera-core:$cameraxVersion") // Implementação Camera2 (necessária) implementation("androidx.camera:camera-camera2:$cameraxVersion") // Integração com Lifecycle implementation("androidx.camera:camera-lifecycle:$cameraxVersion") // Caso de uso VideoCapture implementation("androidx.camera:camera-video:$cameraxVersion") // PreviewView e componentes de UI da câmera implementation("androidx.camera:camera-view:$cameraxVersion") // Opcional: Extensions (Modo noturno, HDR, etc.) implementation("androidx.camera:camera-extensions:$cameraxVersion") // Opcional: Efeitos em tempo real implementation("androidx.camera:camera-effects:$cameraxVersion") } android { // CameraX requer bytecode Java 11 compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } } ``` O Manifest precisa de declarações de recursos e permissões: ```xml ``` Os padrões relacionados para [Kotlin Coroutines](/blog/android/mastering-kotlin-coroutines) se aplicam ao envolver chamadas ListenableFuture do CameraX em funções suspend. ## O que o CameraX 1.6 Muda para Apps em Produção O CameraX 1.6 trouxe três mudanças que afetam implementações existentes: 1. **Backend CameraPipe**: A stack de câmera interna agora usa CameraPipe, a mesma arquitetura da câmera Pixel. Isso melhora o desempenho em dispositivos Pixel e fornece uma base mais limpa para recursos avançados. O código existente não precisa de mudanças. 2. **Media3 Muxer por padrão**: O VideoCapture agora usa Media3 Muxer em vez de MediaMuxer. Isso melhora a resiliência a crashes: se o app terminar durante a gravação, o arquivo de vídeo permanece reproduzível. A superfície da API permanece inalterada. 3. **API SessionConfig estável**: Os apps agora podem configurar ajustes avançados de câmera através do SessionConfig sem anotações experimentais. Isso habilita recursos como uso simultâneo de câmeras frontal/traseira em dispositivos compatíveis. **Caminho de migração**: Atualizar a versão da dependência. Testar em dispositivos que anteriormente tinham problemas. As [notas de lançamento do CameraX](https://developer.android.com/jetpack/androidx/releases/camera) documentam quaisquer mudanças de comportamento entre versões. - O CameraX usa vinculação lifecycle-aware: `bindToLifecycle()` conecta casos de uso tanto ao lifecycle da câmera quanto da Activity - Os modos de ImageCapture trocam latência por qualidade: escolher com base no caso de uso, não na capacidade do dispositivo - VideoCapture requer configuração do Recorder antes de vincular: preparar as opções de saída antes de iniciar - O tratamento de permissões deve explicar o propósito antes de solicitar: reduz as taxas de rejeição - O CameraX 1.6 migrou para CameraPipe internamente: nenhuma mudança de API necessária, mas testar em dispositivos-alvo - As perguntas de entrevista focam em gerenciamento de lifecycle, combinações de casos de uso e comparação com Camera2 --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pt/blog/android/camerax-photo-video-capture-interview-questions