android kotlin - Get all music on sd card

MainActivity.kt

package com.cfsuman.kotlintutorials

import android.app.Activity
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.widget.*


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

        // get the widgets reference from XML layout
        val button = findViewById<Button>(R.id.button)
        val listView = findViewById<ListView>(R.id.listView)


        // Important : handle the runtime permission
        // Check runtime permission to read external storage


        // Button click listener
        button.setOnClickListener{
            // Disable the button itself
            it.isEnabled = false

            // Get the external storage/sd card music files list
            val list:MutableList<Music> = musicFiles()

            // Get the sd card music titles list
            val titles = mutableListOf<String>()
            for (music in list){titles.add(music.title)}

            // Display external storage music files list on list view
            val adapter = ArrayAdapter(
                this,
                android.R.layout.simple_list_item_1,titles
            )
            listView.adapter = adapter
        }
    }
}



// Get all music files list from external storage/sd card
fun Context.musicFiles():MutableList<Music>{
    // Initialize an empty mutable list of music
    val list:MutableList<Music> = mutableListOf()

    // Get the external storage media store audio uri
    val uri: Uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
    //val uri: Uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI

    // IS_MUSIC : Non-zero if the audio file is music
    val selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0"

    // Sort the musics
    val sortOrder = MediaStore.Audio.Media.TITLE + " ASC"
    //val sortOrder = MediaStore.Audio.Media.TITLE + " DESC"

    // Query the external storage for music files
    val cursor: Cursor? = this.contentResolver.query(
        uri, // Uri
        null, // Projection
        selection, // Selection
        null, // Selection arguments
        sortOrder // Sort order
    )

    // If query result is not empty
    cursor?.apply {
        if (cursor.moveToFirst()){
            val id:Int = cursor.getColumnIndex(
                MediaStore.Audio.Media._ID)
            val title:Int = cursor.getColumnIndex(
                MediaStore.Audio.Media.TITLE)

            // Now loop through the music files
            do {
                val audioId:Long = cursor.getLong(id)
                val audioTitle:String = cursor.getString(title)

                // Add the current music to the list
                list.add(Music(audioId,audioTitle))
            }while (cursor.moveToNext())
        }
    }

    // Finally, return the music files list
    return  list
}


// Initialize a new data class to hold music data
data class Music(val id:Long, val title:String)
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#DCDCDC"
    android:padding="24dp">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SD Card Music List"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ListView
        android:id="@+id/listView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/button" />

</androidx.constraintlayout.widget.ConstraintLayout>
AndroidManifest.xml [Permission]

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
More android examples