1

I'm trying to scan all the music files from a specified folder and I am encountering a performance problem combined with an app close.

My approach is to first get all the music files from the phone using:

String[] projection = { 
        MediaStore.Audio.Media._ID,
        MediaStore.Audio.Media.DISPLAY_NAME,
        MediaStore.Audio.Media.DATA, 
        MediaStore.Audio.Media.TITLE 
};

String selection = MediaStore.Audio.Media.IS_MUSIC + "!=" + 0;

cursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                      projection, 
                      selection, 
                      null, 
                      MediaStore.Audio.Media.TITLE + " ASC");

Then I get the location for each of the fetched files using:

columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);

If the file location is within a specified folder, I add it to the list that will be displayed on screen.

The problem with this approach is that it is not performing well.

It hangs for 4-5 seconds.

If I scroll the list the app closes.

Below is the full code I'm using right now:

private String[] getTrackList() {
    String[] result = null;
    String[] projection = {
            MediaStore.Audio.Media._ID,
            MediaStore.Audio.Media.DISPLAY_NAME,
            MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.TITLE
    };

    String selection = MediaStore.Audio.Media.IS_MUSIC + "!=" + 0;

    cursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            projection,
            selection,
            null,
            MediaStore.Audio.Media.TITLE + " ASC");

    result = new String[cursor.getCount()];
    int position = 0;

    for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
        getSearchableDir("/mnt/sdcard/Music/"); //See below
        columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
        String currentDir = cursor.getString(columnIndex).substring(0,
                cursor.getString(columnIndex).lastIndexOf("/") + 1);

        if (searchableDir.contains(currentDir)) {
            columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE);
            result[position] = cursor.getString(columnIndex);
            position++;
        }
    }
    return result;
}

// Function for recursively fetching all the sub-directories
private void getSearchableDir(String path) {
    searchableDir.add(path);
    File root = new File(path);
    File[] list = root.listFiles();
    for (File f : list) {
        if (f.isDirectory()) {
            searchableDir.add(f.getAbsolutePath());
            getSearchableDir(f.getAbsolutePath());
        }
    }
}
Rob Kielty
  • 7,958
  • 8
  • 39
  • 51
reiley
  • 3,759
  • 12
  • 58
  • 114

1 Answers1

0

I think it's safe to say that getSearchableDir is the performance hog here.

Re-factor the code so that this function is not called.

Rob Kielty
  • 7,958
  • 8
  • 39
  • 51