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