Android Take Photo from Camera and Gallery

Taking pictures or photos can’t get any easier. Well, what I am saying that it is super easy and simple. I will show you how to take photo from camera and gallery using Intent on Android. Both taking pictures can be implemented just using an Intent, cool right? So, let’s code!

What the app will look like?

The app will look like this after you finish this tutorial:

Android Take Photo from Camera and Gallery

What will you learn?

  • Understand how to take a picture from the gallery.
  • Understand how to take a photo from the Android camera.
  • Using FileProvider to create and save a photo to application external directory.

Note: In this post, I used Android Studio 3.5.3, make sure you use the latest Android Studio, or if you already install it, be sure to check the latest update. The Kotlin version that I used is Kotlin 1.3.61.

Getting Started – Take Photo from Camera and Gallery 

Open your Android Studio and choose to Start a new Android Studio Project. Then set the Application Name CameraGalleryPicker and select Kotlin as the language. Give the Activity Name MainActivity and wait until the Android Studio finishes preparing your project.

Open activity_main.xml inside res/layout directory and replace the code given below:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="vertical"
       android:layout_centerInParent="true"
       android:layout_margin="30dp">

       <ImageView
           android:id="@+id/ivImage"
           android:layout_width="match_parent"
           android:layout_height="200dp"
           android:src="#dedede"
           />

       <Button
           android:id="@+id/btCapturePhoto"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:layout_marginTop="20dp"
           android:background="@color/colorPrimary"
           android:textColor="@android:color/white"
           android:text="Capture Photo"
           />

       <Button
           android:id="@+id/btOpenGallery"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:layout_marginTop="10dp"
           android:background="@color/colorAccent"
           android:textColor="@android:color/white"
           android:text="Open Gallery"
           />

   </LinearLayout>

</RelativeLayout>

The layout will consist of an ImageView to display a picture or photo later and two Buttons. The first Button is to capture a photo from the Camera and the other is to open the gallery app.

Next, open the AndroidManifest.xml file and proceed to the next step.

Defining Permission on Manifest file

Add some codes inside the <manifest> tag like this:

<manifest … >

   <uses-feature android:name="android.hardware.camera" android:required="true" />

   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
   <uses-permission android:name="android.permission.CAMERA" />

   ...
</manifest>

The <uses-feature> is a tag that allows restriction of visibility of your app on Google Play. that means, only devices that have a camera can view your app on Google Play. This indicates that you set your app depends on having a camera.

The remaining codes are <uses-permission>. It is for setting permission on your app, which in your case here is reading external storage and camera. So all good? Proceed to the next step.

Start Coding

Next, open MainActivity.kt file. Write the code below inside it.

package com.thesimplycoder.cameragallerypicker

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*

class MainActivity : AppCompatActivity() {

   private val REQUEST_PERMISSION = 100

   private val REQUEST_IMAGE_CAPTURE = 1
   private val REQUEST_PICK_IMAGE = 2

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

       btCapturePhoto.setOnClickListener {
           openCamera()
       }

       btOpenGallery.setOnClickListener {
           openGallery()
       }
   }

   override fun onResume() {
       super.onResume()
       checkCameraPermission()
   }

   private fun checkCameraPermission() {
       if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
               != PackageManager.PERMISSION_GRANTED) {

           ActivityCompat.requestPermissions(this,
               arrayOf(Manifest.permission.CAMERA),
               REQUEST_PERMISSION)
       }
   }

   private fun openCamera() {
       Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { intent ->
           intent.resolveActivity(packageManager)?.also {
               startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
           }
       }
   }

   private fun openGallery() {
       Intent(Intent.ACTION_GET_CONTENT).also { intent ->
           intent.type = "image/*"
           intent.resolveActivity(packageManager)?.also {
               startActivityForResult(intent, REQUEST_PICK_IMAGE)
           }
       }
   }

   override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
       if (resultCode == RESULT_OK) {

           if (requestCode == REQUEST_IMAGE_CAPTURE) {
               val bitmap = data?.extras?.get("data") as Bitmap
               ivImage.setImageBitmap(bitmap)
           }

           else if (requestCode == REQUEST_PICK_IMAGE) {
               val uri = data?.getData()
               ivImage.setImageURI(uri)
           }
       }
   }
}

Wow it’s a long code, but don’t worry though, I will explain it:

  • You will see the checkCameraPermission() function, it is a function to check if your app is already given permission to access the camera or not. Starting from Android 6.0 (Marshmallow), permission must be granted on inside a running application. For more info see here.
  • The openCamera() function contains an Intent for opening a camera. It requires a MediaStore.ACTION_IMAGE_CAPTURE to capture a picture. Then call the startActivityForResult() to execute the intent.
  • The openGallery() function is similar to openCamera() function, the difference is just it requires a MediaStore.ACTION_GET_CONTENT. You will have to set which type of file that will be selected from the gallery via intent.type.

Finally, the onActivityResult() will display the result of the captured image and open gallery intent. So you will display the image as a Bitmap to the ImageView.

Run the app and try to capture an image from the Capture Photo button. To select an image from the phone gallery, use the Open Gallery button.

But first, allow all permission requests before you take the picture.

Android Take Photo from Camera and Gallery permission

Capturing a photo:

Opening an image from the gallery:

Basically this is just simple as it is. The next one is capturing a photo using a FileProvider.

Capturing a photo using FileProvider

Add this createCapturedPhoto() function inside the MainActivity.kt file:

lateinit var currentPhotoPath: String

@Throws(IOException::class)
private fun createCapturedPhoto(): File {
   val timestamp: String = SimpleDateFormat("yyyyMMdd-HHmmss", Locale.US).format(Date())
   val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)

   return File.createTempFile("PHOTO_${timestamp}",".jpg", storageDir).apply {
       currentPhotoPath = absolutePath
   }
}

Modify the openCamera() function like this:

private fun openCamera() {
   Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { intent ->
       intent.resolveActivity(packageManager)?.also {

           val photoFile: File? = try {
               createCapturedPhoto()
           } catch (ex: IOException) {
               // If there is error while creating the File, it will be null
               null
           }

           photoFile?.also {
               val photoURI = FileProvider.getUriForFile(
                   this,
                   "${BuildConfig.APPLICATION_ID}.fileprovider",
                   it
               )

               intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
               startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
           }
       }
   }
}

Next, also modify the onActivityResult() method:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
   if (resultCode == RESULT_OK) {

       if (requestCode == REQUEST_IMAGE_CAPTURE) {
           val uri = Uri.parse(currentPhotoPath)
           ivImage.setImageURI(uri)
       }

       else if (requestCode == REQUEST_PICK_IMAGE) {
           val uri = data?.getData()
           ivImage.setImageURI(uri)
       }
   }
}

Open the AndroidManifest.xml file add another permission here:

<manifest … >
   ...

   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
  	 android:maxSdkVersion="18" />
   ...
</manifest>

Also, add a <provider> tag inside the <application> tag:

<application … >
   ...
   <provider
       android:name="androidx.core.content.FileProvider"
       android:authorities="${applicationId}.fileprovider"
       android:exported="false"
       android:grantUriPermissions="true">
       <meta-data
           android:name="android.support.FILE_PROVIDER_PATHS"
           android:resource="@xml/provider_paths"/>
   </provider>
   ...
</application>

Next, add a new XML resource file named xml/provider_paths.xml.

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
   <external-files-path name="my_images" path="Android/data/com.thesimplycoder.cameragallerypicker/files/Pictures" />
   <external-path name="external_storage_root" path="." />
</paths>

These codes are necessary because we use getExternalFilesDir to save the image file. You can run your app again and voila! You just finish this tutorial, great!

Where to go next?

You can download this full code from the link below:

Download final code

Be sure to check my other cool posts here about:

I hope you like my post, comment and share it with love!

You may also like...

1 Response

  1. February 24, 2020

    […] Android Take Photo from Camera and Gallery […]

Join the discussion...

This site uses Akismet to reduce spam. Learn how your comment data is processed.