Getting list of images from a folder in android kotlin
Asked Answered
B

4

7

I'm trying to get list of images from a folder using this function

var gpath:String = Environment.getExternalStorageDirectory().absolutePath
var spath = "testfolder"
var fullpath = File(gpath + File.separator + spath)
var list = imageReader(fullpath)

fun imageReader(root : File):ArrayList<File>{
    val a : ArrayList<File> ? = null
    val files = root.listFiles()
    for (i in 0..files.size){
        if (files[i].name.endsWith(".jpg")){
            a?.add(files[i])
        }
    }
    return a!!
}

but i have these exceptions :

java.lang.ArrayIndexOutOfBoundsException:length=3;index=3

kotin.kotlinNullPointerException

I've read about this problem but i have no idea how to fix it,

any help please?

Broncho answered 4/7, 2018 at 7:51 Comment(5)
Since the indexing of the Array is zero-based, the last element would be files.size - 1.Aprilette
thanks, it fixed the first exception, but NullPointerException still there, any idea ?Broncho
@Broncho Please provide full logcat error and code where you trying to call function.Kero
@Broncho It seems looking you need to pass fullpath instead of path in var list = imageReader(path) check my answer for same and apply.Kero
@Broncho Check my updated answer for your solution.Kero
K
6

For Null Pointer you may need to change and pass fullpath instead of path inside var list = imageReader(path).

Wrong

var fullpath = File(gpath + File.separator + spath)
var list = imageReader(path)

Right

var gpath:String = Environment.getExternalStorageDirectory().absolutePath
var spath = "testfolder"
var fullpath = File(gpath + File.separator + spath)
var list = imageReader(fullpath)

EDIT 1

I have made few changes to function and apply it inside override fun onCreate as below.

var gpath: String = Environment.getExternalStorageDirectory().absolutePath
var spath = "Download"
var fullpath = File(gpath + File.separator + spath)
Log.w("fullpath", "" + fullpath)
imageReaderNew(fullpath)

Function

fun imageReaderNew(root: File) {
    val fileList: ArrayList<File> = ArrayList()
    val listAllFiles = root.listFiles()

    if (listAllFiles != null && listAllFiles.size > 0) {
        for (currentFile in listAllFiles) {
            if (currentFile.name.endsWith(".jpeg")) {
                // File absolute path
                Log.e("downloadFilePath", currentFile.getAbsolutePath())
                // File Name
                Log.e("downloadFileName", currentFile.getName())
                fileList.add(currentFile.absoluteFile)
            }
        }
        Log.w("fileList", "" + fileList.size)
    }
}

Logcat Output

W/fullpath: /storage/emulated/0/Download
E/downloadFilePath: /storage/emulated/0/Download/download.jpeg
E/downloadFileName: download.jpeg
E/downloadFilePath: /storage/emulated/0/Download/images.jpeg
E/downloadFileName: images.jpeg
E/downloadFilePath: /storage/emulated/0/Download/images (1).jpeg
E/downloadFileName: images (1).jpeg
Kero answered 4/7, 2018 at 8:13 Comment(6)
sorry my wrong , i edited the question, but this is not the problem, using debugging mode and BreakPoints i see the the function return (a) as nullBroncho
and im 100% certain there are .jpg files in the provided pathBroncho
@Broncho Check my updated answer made few changes in function and improved this will solve you all issues. Made it easy.Kero
@Broncho Glad to help you !! Also Upvote the answer so it will be helpful to future visitors. :)Kero
I get "Unresolved reference: Environment"Clevelandclevenger
this only lists the folders, it doesn't list any fileJacquard
K
5
fun imageReader(root : File):ArrayList<File>{
    val a : ArrayList<File> ? = null
    val files = root.listFiles()
    for (i in 0..files.size-1){
        if (files[i].name.endsWith(".jpg")){
            a?.add(files[i])
        }
    }
    return a!!
}
Klaus answered 4/7, 2018 at 7:55 Comment(1)
greatly fixed the first exception but NullPointerException still there, any idea?Broncho
T
1

By using MediaStore we can achieve count of image inside a folder and we will add one more check to prevent getting image of subfolders of current folder.

 fun getImageCountInDirectory(context: Context, directoryPath: String): Int {
    var imageCount = 0

    val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
    val sortOrder = MediaStore.Images.Media.DATE_MODIFIED + " DESC"
    val selection = "${MediaStore.Images.Media.DATA} like ? and ${MediaStore.Images.Media.DATA} not like ?"
    val selectionArgs = arrayOf("$directoryPath/%", "$directoryPath/%/%") // use % as a wildcard character to select all files inside the directory, and exclude subdirectories

    val cursor = context.contentResolver.query(
        uri,
        null,
        selection,
        selectionArgs,
        sortOrder
    )
    if (cursor != null) {
        imageCount = cursor.count
        cursor.close()
    }

    return imageCount
}

This function will return an integer value and it is the total number of image files inside the folder. And we are using the not like operator and adding %/% to the selectionArgs array to select all files whose path doesn't contain a subdirectory.

Traction answered 17/2, 2023 at 9:38 Comment(0)
S
0

The above answer is right but it declares a as null and then in loop uses null save. Therefore it detects images but does not add them to the list and the list returns null.

fun imageReader(root: File): ArrayList < File > {
  val a: ArrayList < File > = ArrayList()
  if (root.exists()) {
    val files = root.listFiles()
    if (files.isNotEmpty()) {
      for (i in 0..files.size - 1) {
        if (files[i].name.endsWith(".jpg")) {
          a.add(files[i])
        }
      }
    }
  }
  return a!!
}
Southwards answered 6/1, 2020 at 19:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.