Sunday, May 13, 2018

android kotlin - Get all music on sd card

MainActivity.kt

package com.cfsuman.test

import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.provider.MediaStore
import android.widget.ArrayAdapter
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity() {

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

        // Important : handle the runtime permission
        if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.M){
            // Check runtime permission to read external storage
        }

        // Button click listener
        button.setOnClickListener{
            // 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)
            list_view.adapter = adapter
        }
    }
}


// Extension method to 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
    if (cursor!= null && 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"?>
<LinearLayout
    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"
    tools:context="com.cfsuman.test.MainActivity"
    android:orientation="vertical"
    android:padding="16dp"
    android:background="#d8edf5"
    >
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SD Card Music List"
        />
    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />
</LinearLayout>
AndroidManifest.xml [Permission]

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