Я создаю музыкальный плеер, который получает тег BP3 ID3v2 из всех mp3-файлов на устройстве и позволяет сортировать и фильтровать BPM. Чтобы получить тег, я использую библиотеку mp3agic. Оказывается, что для получения этой метки требуется некоторое время для каждой песни, и выполнение выборки при добавлении каждой песни в мой список песен временно покажет плеер. Я не уверен, должен ли я использовать AsyncTask во всем списке, когда это делается для создания или AsyncTask для каждого элемента, чтобы получить его BPM и вставить его в песню или даже с помощью другого более быстрого метода получения значения BPM. Может ли кто-нибудь предложить какие-либо указания?Выполнять медленную задачу по большому количеству данных в RecyclerView
Вот мой код, чтобы получить BPM:
public int getBpmFromId(long id) {
int bpm = -1;
Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, Long.toString(id));
try {
Mp3File file = new Mp3File(getRealPathFromURI(getApplicationContext(), uri));
if(file.hasId3v2Tag()) {
ID3v2 id3v2Tag = file.getId3v2Tag();
bpm = id3v2Tag.getBPM();
Log.d("MP3AGIC", "Got BPM for track: " + id + ": " + bpm);
}
} catch (Exception e) {
e.printStackTrace();
}
return bpm;
}
и вот код, я использую, чтобы построить свой список песен:
public void getSongList() {
ContentResolver musicResolver = getContentResolver();
Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selectionMimeType = MediaStore.Files.FileColumns.MIME_TYPE + "=?";
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0 AND " + selectionMimeType;
String sortOrder = null;
String[] projection = null;
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("mp3");
String[] selectionArgsMp3 = new String[] { mimeType };
Cursor musicCursor = musicResolver.query(musicUri, projection, selection, selectionArgsMp3, sortOrder);
if(musicCursor != null && musicCursor.moveToFirst()) {
int idColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media._ID);
int titleColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
int artistColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
do {
long id = musicCursor.getLong(idColumn);
String title = musicCursor.getString(titleColumn);
String artist = musicCursor.getString(artistColumn);
//bpm processing
int bpm = getBpmFromId(id);
songList.add(new Song(id, title, artist));
} while (musicCursor.moveToNext());
}
if(musicCursor != null)
musicCursor.close();
}
EDIT: Кажется, что то, что может быть так долго получает путь к файлу с Ури, что делается в этом методе:
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
Я не знаю, как, или я Я могу, оптимизировать это.