Take Picture with Camera Intent - Android Studio - Compose
📸 Take Picture with Camera Intent in Android Studio (Compose) — Complete Guide
Learn how to capture images using the Camera Intent in Android Studio with Compose. This step-by-step tutorial covers everything you need to implement a built-in camera feature in your Android app. You’ll understand how to open the camera, handle permissions, save the captured image, and display it inside your application.
Whether you’re a beginner or an experienced Android developer, this guide will help you integrate camera functionality quickly and efficiently using clean and simple Java code.
What this post covers:
Requesting camera permissions
Launching the Camera Intent
Receiving the captured image
Displaying and saving the photo
Common errors & their solutions
Perfect for Android developers building apps that require image capturing features such as profile photos, scanning, media apps, and more.
Code:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <!--Adding Camera, Write External Storage Permission--> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
MainActivity.kt
package com.technifysoft.myapplication import android.Manifest import android.app.Activity import android.content.ContentValues import android.content.Intent import android.net.Uri import android.os.Build import android.os.Bundle import android.provider.MediaStore import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.BlendMode.Companion.Color import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import coil.compose.rememberAsyncImagePainter import coil.request.ImageRequest import com.technifysoft.myapplication.ui.theme.MyApplicationTheme class MainActivityCompose : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { MainUi() } } } @Composable fun MainUi() { val context = LocalContext.current var imageUri by remember { mutableStateOf<Uri?>(null) } var lastModified by remember { mutableStateOf(System.currentTimeMillis()) } // CAMERA RESULT val cameraLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.StartActivityForResult() ) { result -> if (result.resultCode == Activity.RESULT_OK) { imageUri?.let { uri -> // Force update so the image becomes readable val values = ContentValues().apply { put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis()) } context.contentResolver.update(uri, values, null, null) // Force recomposition → refresh painter cache lastModified = System.currentTimeMillis() } } else { Toast.makeText(context, "Cancelled!", Toast.LENGTH_SHORT).show() } } // Permissions val permissionLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.RequestMultiplePermissions() ) { permissions -> val allGranted = permissions.values.all { it } if (allGranted) { pickImageFromCamera(context) { uri -> imageUri = uri val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) intent.putExtra(MediaStore.EXTRA_OUTPUT, uri) cameraLauncher.launch(intent) } } else { Toast.makeText(context, "Permissions denied", Toast.LENGTH_SHORT).show() } } Column( modifier = Modifier .fillMaxSize() .padding(20.dp), horizontalAlignment = Alignment.CenterHorizontally ) { imageUri?.let { uri -> Image( painter = rememberAsyncImagePainter( model = "$uri?t=$lastModified" // force reload cache ), contentDescription = "Captured Image", modifier = Modifier .fillMaxWidth() .height(350.dp), contentScale = ContentScale.Crop ) } Spacer(modifier = Modifier.height(20.dp)) Button(onClick = { val requiredPermissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) arrayOf(Manifest.permission.CAMERA) else arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE) permissionLauncher.launch(requiredPermissions) }) { Text("Capture Image") } } } fun pickImageFromCamera( context: android.content.Context, onImageUriCreated: (Uri) -> Unit ) { val contentValues = ContentValues().apply { put(MediaStore.Images.Media.TITLE, "TEMP_IMAGE") put(MediaStore.Images.Media.DESCRIPTION, "Captured by Camera") } val uri = context.contentResolver.insert( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues ) onImageUriCreated(uri!!) } /** * GreetingPreview is a composable function for previewing the MainUI in Android Studio. * It is annotated with @Preview to enable live preview. * */ @Preview(showBackground = true) @Composable private fun GreetingPreview() { MyApplicationTheme { MainUi() } }

Comments
Post a Comment