Kotlin Pick Video From Gallery Or Capture From Camera In Android

listview section header kotlin, kotlin pick video from gallery or capture from camera, kotlin custom spinner with image, pull to refresh listview android, swipe to refresh recyclerview android, expandablelistview in kotlin, Kotlin Horizontal Progressbar Android, kotlin image slider from url, Kotlin GIF Animated Splash Screen, Kotlin RecyclerView Sectioned Header, kotlin indeterminate circular progressbar, android dexter kotlin, kotlin digital signature view, kotlin alertdialog with edittext, elasticsearch windows, android dexter kotlin

Read about Kotlin Pick Video From Gallery Or Capture From Camera In Android.

In this tutorial, you will learn how to select or pick video from gallery of the android device.

Other than simply select, user will also be able to capture video from camera and it will display this captured video. We will do all these things using Kotlin as the source language.

First of all, check the following video to get more idea about working of this tutorial.

 

 

Now follow all the below steps to generate example with Kotlin in Android.

Step 1. New Project and Permissions

Create a new project in the android studio.

Here during making a new project, set the Kotlin as the primary source language and select “empty activity” as the main activity of the project.

Now, in your new project, go to AndroidManifest.xml file.

Add the following lines in AndroidManifest.xml file.

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

We will ask for runtime permissions later in the Main Activity.

Now for adding a gradle line for library, go to build.gradle(Module:app) and write the below line

 implementation 'com.karumi:dexter:5.0.0'

This line is for dexter library which will help us to simply the process of asking the runtime permissions.

Step 2. Changing Main Files

Go to activity_main.xml file. Write down the following source block in it.

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

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/btn"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="40dp"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Select or Capture Video" />

    <VideoView
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:layout_gravity="center"
            android:layout_marginTop="20dp"
            android:scaleType="fitXY"
            android:src="@mipmap/ic_launcher"
            android:id="@+id/vv"/>
</LinearLayout>

I have added one button and one video view in this file.

Button will led user to gallery or camera based on his choice.

After selecting or capturing the video, we will preview this video in video view.

Now, In your MainActivity.kt file, add the below code block.

import android.Manifest
import android.app.Activity
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import android.content.Intent;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.VideoView;

class MainActivity : AppCompatActivity() {

    private var btn: Button? = null
    private var videoView: VideoView? = null
    private val VIDEO_DIRECTORY = "/demonutsVideoooo"
    private val GALLERY = 1
    private val CAMERA = 2

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

        requestMultiplePermissions()

        btn = findViewById(R.id.btn) as Button
        videoView = findViewById(R.id.vv) as VideoView

        btn!!.setOnClickListener(View.OnClickListener { showPictureDialog() })

    }

    private fun showPictureDialog() {
        val pictureDialog = AlertDialog.Builder(this)
        pictureDialog.setTitle("Select Action")
        val pictureDialogItems = arrayOf("Select video from gallery", "Record video from camera")
        pictureDialog.setItems(
            pictureDialogItems
        ) { dialog, which ->
            when (which) {
                0 -> chooseVideoFromGallary()
                1 -> takeVideoFromCamera()
            }
        }
        pictureDialog.show()
    }

    fun chooseVideoFromGallary() {
        val galleryIntent = Intent(
            Intent.ACTION_PICK,
            android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI
        )

        startActivityForResult(galleryIntent, GALLERY)
    }

    private fun takeVideoFromCamera() {
        val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
        startActivityForResult(intent, CAMERA)
    }

    public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

        Log.d("result", "" + resultCode)
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_CANCELED) {
            Log.d("what", "cancle")
            return
        }
        if (requestCode == GALLERY) {
            Log.d("what", "gale")
            if (data != null) {
                val contentURI = data!!.data

                val selectedVideoPath = getPath(contentURI)
                Log.d("path", selectedVideoPath)

                videoView!!.setVideoURI(contentURI)
                videoView!!.requestFocus()
                videoView!!.start()

            }

        } else if (requestCode == CAMERA) {
            Log.d("what", "camera")
            val contentURI = data!!.data
            val recordedVideoPath = getPath(contentURI)
            Log.d("frrr", recordedVideoPath)

            videoView!!.setVideoURI(contentURI)
            videoView!!.requestFocus()
            videoView!!.start()
        }
    }

    fun getPath(uri: Uri?): String? {
        val projection = arrayOf(MediaStore.Video.Media.DATA)
        val cursor = contentResolver.query(uri!!, projection, null, null, null)
        if (cursor != null) {
            // HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
            // THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
            val column_index = cursor!!
                .getColumnIndexOrThrow(MediaStore.Video.Media.DATA)
            cursor!!.moveToFirst()
            return cursor!!.getString(column_index)
        } else
            return null
    }

    private fun requestMultiplePermissions() {
        Dexter.withActivity(this)
            .withPermissions(
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA
            )
            .withListener(object : MultiplePermissionsListener {
                override fun onPermissionsChecked(report: MultiplePermissionsReport) {
                    // check if all permissions are granted
                    if (report.areAllPermissionsGranted()) {
                        Toast.makeText(applicationContext, "All permissions are granted by user!", Toast.LENGTH_SHORT)
                            .show()
                    }

                    // check for permanent denial of any permission
                    if (report.isAnyPermissionPermanentlyDenied) {
                        // show alert dialog navigating to Settings
                        //openSettingsDialog()
                    }
                }

                override fun onPermissionRationaleShouldBeShown(
                    permissions: List<PermissionRequest>,
                    token: PermissionToken
                ) {
                    token.continuePermissionRequest()
                }
            }).withErrorListener { Toast.makeText(applicationContext, "Some Error! ", Toast.LENGTH_SHORT).show() }
            .onSameThread()
            .check()
    }

}

Diving in Above

Now let us see the all the lines of Main activity in details.

First of all, see the following

  private var btn: Button? = null
    private var videoView: VideoView? = null
    private val VIDEO_DIRECTORY = "/demonutsVideoooo"
    private val GALLERY = 1
    private val CAMERA = 2

I have created the objects of Button class and VideoView class in line one and two respectively.

Third line is the string variable. Fourth is the integer having value as “1” and fifth is also integer with value “2”

Now inside onCreate() method, there is another function having name “requestMultiplePermissions()”

“requestMultiplePermissions()” method will help us to implement the runtime permissions in an easy manner.

Below is the source lines for “requestMultiplePermissions()” function.

 private fun requestMultiplePermissions() {
        Dexter.withActivity(this)
            .withPermissions(
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA
            )
            .withListener(object : MultiplePermissionsListener {
                override fun onPermissionsChecked(report: MultiplePermissionsReport) {
                    // check if all permissions are granted
                    if (report.areAllPermissionsGranted()) {
                        Toast.makeText(applicationContext, "All permissions are granted by user!", Toast.LENGTH_SHORT)
                            .show()
                    }

                    // check for permanent denial of any permission
                    if (report.isAnyPermissionPermanentlyDenied) {
                        // show alert dialog navigating to Settings
                        //openSettingsDialog()
                    }
                }

                override fun onPermissionRationaleShouldBeShown(
                    permissions: List<PermissionRequest>,
                    token: PermissionToken
                ) {
                    token.continuePermissionRequest()
                }
            }).withErrorListener { Toast.makeText(applicationContext, "Some Error! ", Toast.LENGTH_SHORT).show() }
            .onSameThread()
            .check()
    }

You can see that above function is using the Dexter class in it’s very first line.

This Dexter class comes from the dexter library that we have added in the gradle file.

I have added the same permissions (READ EXTERNAL STORAGE, WRITE EXTERNAL STORAGE, CAMERA) in this “requestMultiplePermissions()” method as we have added in the AndroidManifest.xml file.

Now get your attention towards the below coding lines

 btn = findViewById(R.id.btn) as Button
        videoView = findViewById(R.id.vv) as VideoView

        btn!!.setOnClickListener(View.OnClickListener { showPictureDialog() })

First line will find the Button view using it’s id and similarly, second line will find video view with it’ id.

When the user will click the button, compiler will run the showPictureDialog() method.

Below is the source code structure for showPictureDialog() method.

  private fun showPictureDialog() {
        val pictureDialog = AlertDialog.Builder(this)
        pictureDialog.setTitle("Select Action")
        val pictureDialogItems = arrayOf("Select video from gallery", "Record video from camera")
        pictureDialog.setItems(
            pictureDialogItems
        ) { dialog, which ->
            when (which) {
                0 -> chooseVideoFromGallary()
                1 -> takeVideoFromCamera()
            }
        }
        pictureDialog.show()
    }

On the button click, compiler will open up one dialog with two options : “Select video from gallery” and “Record video from camera”

If user clicks on “Select video from gallery” , compiler will execute chooseVideoFromGallery() method. For second option, compiler will run takeVideoFromCamera()

Below is the code for  chooseVideoFromGallery() method

  fun chooseVideoFromGallary() {
        val galleryIntent = Intent(
            Intent.ACTION_PICK,
            android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI
        )

        startActivityForResult(galleryIntent, GALLERY)
    }

Above code will open all the videos which are available in the gallery of the android device.

User can select any video from this screen.

Code block for takeVideoFromCamera() method is as the below

 private fun takeVideoFromCamera() {
        val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
        startActivityForResult(intent, CAMERA)
    }

This method will simply open up the camera preview. From this preview, user can record the video.

Now, after selecting video or capturing the video, compiler will run the onActivityResult() method.

 public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

        Log.d("result", "" + resultCode)
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_CANCELED) {
            Log.d("what", "cancle")
            return
        }
        if (requestCode == GALLERY) {
            Log.d("what", "gale")
            if (data != null) {
                val contentURI = data!!.data

                val selectedVideoPath = getPath(contentURI)
                Log.d("path", selectedVideoPath)

                videoView!!.setVideoURI(contentURI)
                videoView!!.requestFocus()
                videoView!!.start()

            }

        } else if (requestCode == CAMERA) {
            Log.d("what", "camera")
            val contentURI = data!!.data
            val recordedVideoPath = getPath(contentURI)
            Log.d("frrr", recordedVideoPath)

            videoView!!.setVideoURI(contentURI)
            videoView!!.requestFocus()
            videoView!!.start()
        }
    }

This method will check if compiler have selected the video from gallery or have captured the video from camera.

For selecting video, compiler will go into if(resultCode == GALLERY)

It will then set the video preview in the video view using the URI of the video. It will also start the video.

Compiler will do the same thing for capturing the video from camera.

You can find JAVA version of this tutorial here : https://demonuts.com/pick-video-gallery-camera-android/

Download Code For kotlin pick video from gallery or capture from camera

https://github.com/demonuts/kotlin-pick-video-from-gallery-or-capture-from-camera