Reputation: 1643
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
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