We know that in many situations our app needs to use the Camera of the device to take pictures, You might know how to use Camera feature in your Android app with Java which is a traditional language for Android
Here we are going to learn how to use Camera feature in our App with Kotlin.
Add permissions
Make sure that you have added the following permissions into your manifest.xml file.
<uses-permission android:name=”android.permission.CAMERA”/>
<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>
<uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE”/>
Set up Layout
We are going to setup Layout file for MainActivity
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:layout_centerInParent="true" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/image_view" android:background="@drawable/img_placehlder" android:layout_gravity="center_horizontal" android:layout_width="200dp" android:layout_height="300dp" /> <Button android:id="@+id/btn_capture" android:text="Capture" android:layout_marginTop="12dp" android:layout_gravity="center_horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </RelativeLayout>
The layout will be like this.

Set Up MainActivity
Now we are going to set up our MainActivity.kt, Have the following methods.
Firstly we need to handle the permissions, From Android 6.0 (Marshmellow) Google introduced Run time permissions. We need to declare the permissions in the manifest.xml file and then request these permissions in runtime so that user can approve or decline each permission. Add the following code to check permissions and request permission
private fun checkPersmission(): Boolean { return (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) } private fun requestPermission() { ActivityCompat.requestPermissions(this, arrayOf(READ_EXTERNAL_STORAGE, CAMERA), PERMISSION_REQUEST_CODE) }
We are going to check this permission in Capture Button click. So if the user is already given the permissions to access Camera and External Storage we can directly open the Camera to take Picture. But we should manage the onRequestPermissionsresult() to open the camera after the request for permissions and if the user accepted it. This includes a method takePicture() which is defined later.
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { when (requestCode) { PERMISSION_REQUEST_CODE -> { if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) &&grantResults[1] == PackageManager.PERMISSION_GRANTED) { takePicture() } else { Toast.makeText(this,"Permission Denied",Toast.LENGTH_SHORT).show() } return } else -> { } } }
Now let’s take a look at takePicture() method. In this method, we set up an Intent to open the Camera. This method consists of a method called createFile() used to create a File to store the Image.
@Throws(IOException::class) private fun createFile(): File { // Create an image file name val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date()) val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES) return File.createTempFile( "JPEG_${timeStamp}_", /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ).apply { // Save a file: path for use with ACTION_VIEW intents mCurrentPhotoPath = absolutePath } }
We need to Configure the FileProvider in our app’s manifest.xml file to add a provider to our application.
<application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.android.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_path"> </meta-data> </provider> ... </application>
Create a new
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="my_images" path="Android/data/com.kotlincodes.cameraintentwithkotlin_android/files/Pictures" /> </paths>
Now we can set an Intent to start Camera to capture an Image as follows
private fun takePicture() { val intent: Intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) val file: File = createFile() val uri: Uri = FileProvider.getUriForFile( this, "com.example.android.fileprovider", file ) intent.putExtra(MediaStore.EXTRA_OUTPUT,uri) startActivityForResult(intent, REQUEST_IMAGE_CAPTURE) }
This method will open the Camera and we can capture an Image. After taking a Picture we need to show this Image on our ImageView. To set the ImageView add the following code
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) { //To get the File for further usage val auxFile = File(mCurrentPhotoPath) var bitmap :Bitmap=BitmapFactory.decodeFile(mCurrentPhotoPath) imageView.setImageBitmap(bitmap) } }
Now we are all set to run the project. Please find the Complete code for MainActivity.kt file below.
MainActivity.kt
package com.kotlincodes.cameraintentwithkotlin_android import android.Manifest.permission.CAMERA import android.Manifest.permission.READ_EXTERNAL_STORAGE import android.app.Activity import android.content.Intent import android.content.pm.PackageManager import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.Uri import android.os.Bundle import android.os.Environment import android.provider.MediaStore import android.support.v4.app.ActivityCompat import android.support.v4.content.ContextCompat import android.support.v4.content.FileProvider import android.support.v7.app.AppCompatActivity import android.view.View import android.widget.Button import android.widget.ImageView import android.widget.Toast import java.io.File import java.io.IOException import java.text.SimpleDateFormat import java.util.* class MainActivity : AppCompatActivity() { lateinit var imageView: ImageView lateinit var captureButton: Button val REQUEST_IMAGE_CAPTURE = 1 private val PERMISSION_REQUEST_CODE: Int = 101 private var mCurrentPhotoPath: String? = null; override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) imageView = findViewById(R.id.image_view) captureButton = findViewById(R.id.btn_capture) captureButton.setOnClickListener(View.OnClickListener { if (checkPersmission()) takePicture() else requestPermission() }) } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { when (requestCode) { PERMISSION_REQUEST_CODE -> { if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) && grantResults[1] == PackageManager.PERMISSION_GRANTED) { takePicture() } else { Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show() } return } else -> { } } } private fun takePicture() { val intent: Intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) val file: File = createFile() val uri: Uri = FileProvider.getUriForFile( this, "com.example.android.fileprovider", file ) intent.putExtra(MediaStore.EXTRA_OUTPUT, uri) startActivityForResult(intent, REQUEST_IMAGE_CAPTURE) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) { //To get the File for further usage val auxFile = File(mCurrentPhotoPath) var bitmap: Bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath) imageView.setImageBitmap(bitmap) } } private fun checkPersmission(): Boolean { return (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) } private fun requestPermission() { ActivityCompat.requestPermissions(this, arrayOf(READ_EXTERNAL_STORAGE, CAMERA), PERMISSION_REQUEST_CODE) } @Throws(IOException::class) private fun createFile(): File { // Create an image file name val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date()) val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES) return File.createTempFile( "JPEG_${timeStamp}_", /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ).apply { // Save a file: path for use with ACTION_VIEW intents mCurrentPhotoPath = absolutePath } } }
That’s it! Now run the project!
The full source code is available here.
Thanks for reading!
