Vinit Shandilya
Vinit Shandilya

Reputation: 1643

Listing audio and video files in ListView

I've written a small program that lists all audio and video files (present on the SD card) in an android ListView. I'm using CursorLoader inside AsyncTask to query MediaStore and then populating my ListView with result data. The program is working fine.

My problem is, every time I launch the app, it takes pretty long time to build the list of media. I understand, it is because of intensive database query. However, I've seen some apps (like stock media player, MX Player, etc.) which scan all media files only for the first time (which may take a while). After that, when the app is launched again, the media list is popped up almost instantaneously. How can I achieve that? Here is my approach:

private void loadAudio() {

    Uri uri1 = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    String selection1 = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
    String sortOrder1 = MediaStore.Audio.Media.TITLE + " ASC";
    ContentResolver cr1 = getBaseContext().getContentResolver();
    Cursor cur1 = cr1.query(uri1, null, selection1, null, sortOrder1);
    int count1 = 0;

    if (cur1 != null) {
        count1 = cur1.getCount();

        if (count1 > 0) {
            while (cur1.moveToNext()) {
                String audioPath = cur1.getString(cur1
                        .getColumnIndex(MediaStore.Audio.Media.DATA));
                //File tempfile = new File(audioPath);
                long albumId = cur1.getLong(cur1.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
                String artist = cur1.getString(cur1.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
                String album = cur1.getString(cur1.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
                String track = cur1.getString(cur1.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
                String data = cur1.getString(cur1.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
                int duration = cur1.getInt(cur1.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
                final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
                Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, albumId);

                Bitmap albumartbitmap = null;
                try {
                    albumartbitmap = MediaStore.Images.Media.getBitmap(getBaseContext().getContentResolver(), albumArtUri);
                } catch (Exception exception) {
                    // log error
                }
                audioList.add(new AudioData(albumId, artist, album, track, data, duration, albumartbitmap, audioPath));
            }
        }
    }
    cur1.close();
}

I'm calling this method inside doInBackground of my AsyncTask:

@Override
    protected Void doInBackground(Void... params) {
        Looper.prepare();
        loadVideo(); //Query media-store and build video list. populate mediaList
        loadAudio(); //Query media-store and build audio list. populate audioList
        return null;
    }

Any help would be appreciated! Thanks in advance!

Upvotes: 1

Views: 709

Answers (1)

Zeppie
Zeppie

Reputation: 179

The only thing I can think of that may give you a faster access time is to build an internal SQL database with your results. When your app opens it would then need to see if the database is present or not. If not it would need to search the sd card, if present you would have all the data loaded into a sql searchable database already. I would still expect you to have some load time issues with a large number or results in the sql database.

If the programs you are referencing have any sort of 'refresh/rebuild' options in them then this is how I would think they are managing it.

The only other option I can think of is that they are somehow saving the entire listview object to an internal file, then just loading the file. I know that saving an entire class to a file is possible in C++ but have never tried it in Java/Android

Upvotes: 1

Related Questions