私のアプリは、曲のタイトル、アーティスト、アルバム、ジャンルなどを含む、デバイスのすべての音楽をリストする必要があります。Androidは入れ子になっていないすべての音楽やジャンルを取得します。 (MediaStore.Audio ...)
私は曲のジャンルを取得するの知っている方法は、このような歌の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が必要です。ありがとう。