我的应用需要列出设备上的所有音乐,包括:歌曲标题,艺术家,专辑,流派等。
我知道如何获得一首歌的流派,就是用这样的歌曲ID创建另一个Cursor
:
Uri uri = MediaStore.Audio.Genres.getContentUriForAudioId("external", (int) id);
Cursor genresCursor = mContentResolver.query(uri, genresProjection, null, null, null);
但是,如果我在列出所有歌曲的Cursor
内执行此操作,则加载时间会增加很多。 (对于我手机上的歌曲数量,从0.5秒到3秒左右)。
这是我的代码:
// If you change this to `false`, it will load a lot quicker.
private static final boolean LOAD_GENRE = true;
private static String[] mediaProjection = {
MediaStore.Audio.AudioColumns._ID,
MediaStore.Audio.AudioColumns.DATA,
MediaStore.Audio.AudioColumns.TITLE,
MediaStore.Audio.AudioColumns.ARTIST,
MediaStore.Audio.AudioColumns.ALBUM,
MediaStore.Audio.AudioColumns.ALBUM_ID,
MediaStore.Audio.AudioColumns.DURATION
};
private static String[] genresProjection = {
MediaStore.Audio.GenresColumns.NAME
};
private ArrayList<MediaMetadataCompat> getAllMusic() {
Uri uriAudio = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = mContentResolver.query(uriAudio, mediaProjection, null, null, null);
if (cursor != null) {
int count = cursor.getCount();
if (count > 0) {
ArrayList<MediaMetadataCompat> audioFiles = new ArrayList<>();
while (cursor.moveToNext()) {
MediaMetadataCompat song = buildFromCursor(cursor);
if (song != null) {
audioFiles.add(song);
}
}
cursor.close();
return audioFiles;
}
}
return new ArrayList<>();
}
private MediaMetadataCompat buildFromCursor(Cursor cursor, boolean loadGenre) {
long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.AudioColumns._ID));
String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DATA));
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.AudioColumns.TITLE));
String artist = ...;
String album = ...;
long albumId = ...;
long duration = ...;
//File file = new File(data);
//if (!file.exists()) {
// Log.e(TAG, "Skipping song because it does not exist: " + title);
// return null;
//}
Uri uri = MediaStore.Audio.Genres.getContentUriForAudioId("external", (int) id);
if (LOAD_GENRE) {
String genre = null;
Cursor genresCursor = mContentResolver.query(uri, genresProjection, null, null, null);
if (genresCursor != null && genresCursor.moveToFirst()) {
int genreColumnIndex = genresCursor.getColumnIndex(MediaStore.Audio.GenresColumns.NAME);
do {
String genreColumn = genresCursor.getString(genreColumnIndex);
if (genre == null) {
genre = genreColumn;
} else {
genre += " " + genre;
}
} while (genresCursor.moveToNext());
genresCursor.close();
}
}
// Workaround to avoid ANOTHER cursor to load album art.
Uri albumArtUri = ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), albumId);
MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, String.valueOf(id))
.put...
.put...;
return builder.build();
}
有什么方法可以改进这段代码,以避免嵌套Cursor
?我已经找到了专辑封面的解决方法。是否有可能以某种方式组合它们? CursorJoiner
会为此工作吗?问题是要获得类型,您需要拥有媒体ID。感谢。
答案 0 :(得分:0)
SO用户Suhaib Roomey最近发布了此消息 (get genre_id and audio_id from audio_genres_map from mediastore)。也许它有助于你想要实现的目标
String[] genresProjection = {
Audio.Genres.Members.AUDIO_ID,
Audio.Genres.Members.GENRE_ID
};
context.getContentResolver().query(Uri.parse("content://media/external/audio/genres/all/members"), genresProjection, null, null, null);