How to choose file in Android programmatically

In this tutorial, I am explaining how to pick multiple files in android using the default file chooser. By using this example, you can select images and files. In my previous post, I explained how to capture images using a content provider.

  • Setup file picking intent for multiple files and registerForActivityResult.
  • on activity, result get the select files URI.
  • Store the image in a defined location from the URI.
  • Display the image from the file location.

Setup File Picking Intent

Once we got the permission next step is to set up the intent to pick multiple images from the gallery or from another location.

val selectImagesActivityResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                if (result.resultCode == Activity.RESULT_OK) {
                    
                }
            }
val intent = Intent(ACTION_GET_CONTENT)
            intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
            intent.type = "*/*"
            selectImagesActivityResult.launch(intent)

In the above code,

Intent.EXTRA_ALLOW_MULTIPLE to true set the intent to select multiple files.

intent.type = "*/*"to allow intent to accept all kinds of files like images, pdf and etc.

if you want to allow only images, use intent.type = "image/*"

Finally, register startActivityResult with the intent we created. This is redirected to the default file chooser to select our needed files.

Get File URI from the result

Once all the files are selected, It will come to the Activity result with the result as a response. The result contains Intent with data.

If you user-selected multiple images, it will come to the intent clipData and if the user selected only one image then we need to check it in intent data.

val selectImagesActivityResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val data: Intent? = result.data
                    //If multiple image selected
                    if (data?.clipData != null) {
                        val count = data.clipData?.itemCount ?: 0
                        for (i in 0 until count) {
                            val imageUri: Uri? = data.clipData?.getItemAt(i)?.uri
                        }
                    }
                    //If single image selected
                    else if (data?.data != null) {
                        val imageUri: Uri? = data.data
                    }
                }
            }

If multiple files are selected, clipData has all the selected file URI. So, loop through the clipdata and get all the file URI.

Get File From URI

Now we are having the URI of the selected files. Let’s get the File from the URI. I have created a method to get the Files from the URI.

private fun getImageFromUri(imageUri: Uri?) : File? {
        imageUri?.let { uri ->
            val mimeType = getMimeType(this@MainActivity, uri)
            mimeType?.let {
                val file = createTmpFileFromUri(this, imageUri,"temp_image", ".$it")
                file?.let { Log.d("image Url = ", file.absolutePath) }
                return file
            }
        }
        return null
    }


    private fun getMimeType(context: Context, uri: Uri): String? {
        //Check uri format to avoid null
        val extension: String? = if (uri.scheme == ContentResolver.SCHEME_CONTENT) {
            //If scheme is a content
            val mime = MimeTypeMap.getSingleton()
            mime.getExtensionFromMimeType(context.contentResolver.getType(uri))
        } else {
            //If scheme is a File
            //This will replace white spaces with %20 and also other special characters. This will avoid returning null values on file name with spaces and special characters.
            MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(File(uri.path)).toString())
        }
        return extension
    }

    private fun createTmpFileFromUri(context: Context, uri: Uri, fileName: String, mimeType: String): File? {
        return try {
            val stream = context.contentResolver.openInputStream(uri)
            val file = File.createTempFile(fileName, mimeType,cacheDir)
            FileUtils.copyInputStreamToFile(stream,file)
            file
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

in the above code, The createTmpFileFromUri() creates the Temp file in the cache directory and writes the selected file in the cache directory using the given URI. The getMimeType() get the type of the file like pdf or jpg.

Finally, getImageFromUri() will return the file location where the selected images are stored in thecache directory.

Display the selected Files

Now we got the file locations of the selected images. let load the files into recyclerview and display. In this example, I have selected images and displayed images in recyclerview.

lateinit var imageAdapter: ImageAdapter
var selectedPaths = mutableListOf<String>()
imageAdapter = ImageAdapter()
rvImages.adapter = imageAdapter

val selectImagesActivityResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val data: Intent? = result.data
                    //If multiple image selected
                    if (data?.clipData != null) {
                        val count = data.clipData?.itemCount ?: 0

                        for (i in 0 until count) {
                            val imageUri: Uri? = data.clipData?.getItemAt(i)?.uri
                            val file = getImageFromUri(imageUri)
                            file?.let {
                                selectedPaths.add(it.absolutePath)
                            }
                        }
                        imageAdapter.addSelectedImages(selectedPaths)
                    }
                    //If single image selected
                    else if (data?.data != null) {
                        val imageUri: Uri? = data.data
                        val file = getImageFromUri(imageUri)
                        file?.let {
                            selectedPaths.add(it.absolutePath)
                        }
                        imageAdapter.addSelectedImages(selectedPaths)
                    }
                }
            }

Deleting the Cache Directory

Once done with all your file operations, we need to clear the files from the cache directory. you can do this by using the below function.

fun deleteTempFiles(file: File = cacheDir): Boolean {
        if (file.isDirectory) {
            val files = file.listFiles()
            if (files != null) {
                for (f in files) {
                    if (f.isDirectory) {
                        deleteTempFiles(f)
                    } else {
                        f.delete()
                    }
                }
            }
        }
        return file.delete()
    }

Screenshots:

How to choose file in Android programmatically
How to choose file in Android programmatically
How to choose file in Android programmatically

Source:

You can download the source on Github.

How do I select a PDF on Android?

In this article, we are going to see how we can implement a PDF picker in android studio and get the Uri and Path of the pdf..
Step 1: Create a New Project. Open a new project. ... .
Step 2: Adding storage permission. ... .
Step 3: Working on XML files..

How do I access files on Android?

Find & open files.
Open your phone's Files app . Learn where to find your apps..
Your downloaded files will show. To find other files, tap Menu . To sort by name, date, type, or size, tap More. Sort by. If you don't see "Sort by," tap Modified or Sort ..
To open a file, tap it..

How do I open file manager in android programmatically?

Intent intent = new Intent(Intent. ACTION_GET_CONTENT); intent. setType("*/*"); Intent i = Intent. createChooser(intent, "View Default File Manager"); startActivityForResult(i, CHOOSE_FILE_REQUESTCODE);

How do I access files in Android Studio?

Right-click on a file or directory to create a new file or directory, save the selected file or directory to your machine, upload, delete, or synchronize. Double-click a file to open it in Android Studio. Android Studio saves files you open this way in a temporary directory outside of your project.