Android Intent to Import Multiple Photos From Gallery (Kotlin)

June 19, 2018

Start intent to select multiple photos from gallery.

class TestFragment : Fragment() {
    companion object {
        private const val REQUEST_PICK_PHOTO = 1
    }

    // ...
}
val intent = Intent()
intent.type = "image/*"
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(Intent.createChooser(intent, "Select Picture"), REQUEST_PICK_PHOTO)

Handle activity result.

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (requestCode == REQUEST_PICK_PHOTO) {
        if (resultCode == RESULT_OK) {
            if (data == null) {
                // something is wrong
            }

            val clipData = data.clipData
            if (clipData != null) { // handle multiple photo
                for (i in 0 until clipData.itemCount) {
                    val uri = clipData.getItemAt(i).uri

                    importPhoto(uri)
                }
            } else { // handle single photo
                val uri = data?.data
                importPhoto(uri)
            }
        }
    }
}

Method to read image file and save it.

fun isImage(context: Context, uri: Uri): Boolean {
    val mimeType = context.contentResolver.getType(uri) ?: return true
    return mimeType.startsWith("image/")
}

private fun createImageFile(dir: File, fileName: String? = null): File {
    if (fileName == null) {
        val timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-kkmmss"))
        return File.createTempFile("IMG_$timestamp", ".jpg", dir)
    }

    return File(dir, fileName)
}

fun copyUriToFile(context: Context, uri: Uri, outputFile: File) {
    val inputStream = context.contentResolver.openInputStream(uri)
    
    // copy inputStream to file using okio
    /*
    val source = Okio.buffer(Okio.source(inputStream))
    val sink = Okio.buffer(Okio.sink(outputFile))

    sink.writeAll(source)

    sink.close()
    source.close()
     */

    val outputStream = FileOutputStream(outputFile)
    inputStream.use { input ->
        outputStream.use { output ->
            input.copyTo(output)
        }
    }
}

fun importPhoto(uri: Uri): Boolean {
    if (!isImage(context, uri)) {
        // not image
        return false
    }

    return try {
        val photoFile = createImageFile(context.cacheDir)
        copyUriToFile(context, uri, photoFile)
        
        // addImageToGallery(photoFile)
        true
    }
    catch (e: IOException) {
        e.printStackTrace()
        // handle error
        false
    }
}
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.