список альбомов в андроиде

Я разрабатываю простой аудиоплеер в Android. Я хочу перечислить альбомы в устройстве.

я попробовал этот код

String where = new String();
where = MediaStore.Audio.Media.IS_MUSIC + "=1";
private Cursor managedCursor;
managedCursor = managedQuery(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        new String[] {  
            MediaStore.Audio.Media.TITLE,
            MediaStore.Audio.Media._ID,
            MediaStore.Audio.Media.ALBUM,       
            MediaStore.Audio.Media.ALBUM_ID,    
            MediaStore.Audio.Media.ARTIST,
            MediaStore.Audio.Media.ARTIST_ID
        },
        where,                                  
        null,                                       
        MediaStore.Audio.Media.DEFAULT_SORT_ORDER   
    );

  ListAdapter adapter = new AlbumListAdapter(
        this,                                   
        R.layout.albumlist_item,                
        managedCursor,                          
        new String[] {                          
            MediaStore.Audio.Media.ALBUM,       
            MediaStore.Audio.Media.ARTIST           
        },
        new int[] {                             
            R.id.text_album, 
            R.id.text_artist 
        }
    );
    setListAdapter(adapter);

Но этот код перечисляет все песни в устройстве.

Какова структура БД магазина Android Media.

Кто-нибудь, пожалуйста, помогите.


person John    schedule 03.02.2012    source источник


Ответы (3)


Вы должны запросить альбомы следующим образом

String[] projection = new String[] { Albums._ID, Albums.ALBUM, Albums.ARTIST, Albums.ALBUM_ART, Albums.NUMBER_OF_SONGS };
String selection = null;
String[] selectionArgs = null;
String sortOrder = Media.ALBUM + " ASC";
Cursor cursor = contentResolver.query(Albums.EXTERNAL_CONTENT_URI, projection, selection, selectionArgs, sortOrder);

http://developer.android.com/reference/android/provider/MediaStore.Audio.Albums.html

Исполнители, плейлисты и жанры можно запросить аналогичным образом, используя правильный EXTERNAL_CONTENT_URI и соответствующую проекцию.

Надеюсь, это поможет...

person JeffG    schedule 20.02.2012
comment
что именно делает ASC? он изменил порядок моего списка медиа, но я не понимаю, что он делает - person Zen; 22.03.2014
comment
ASC упорядочивает результирующий набор в порядке возрастания. В этом примере он упорядочит список в порядке возрастания названия альбома. Таким образом, в алфавитном порядке A, B, C и т. д. Противоположность DESC для убывания - person JeffG; 24.03.2014
comment
Работает отлично. Но он упорядочивает музыкальные файлы, начинающиеся с прописных и строчных букв, отдельно. Поэтому преобразовал все медиафайлы в нижний регистр перед их сортировкой :) - person Zen; 24.03.2014
comment
Вы можете попробовать String sortOrder = lower( + Media.ALBUM +) ASC; Но я не пробовал это и не уверен, что это сработает. Если я хочу выполнить расширенную сортировку, я преобразовываю результаты в объекты, а затем использую Comparator и Collection.sort для их сортировки. надеюсь, это поможет - person JeffG; 24.03.2014
comment
@JeffG Он покажет список альбомов, но также покажет повторяющиеся значения, если нам нужно сделать его уникальным, мы должны использовать DISTINCT для альбомов, но мы не можем получить несколько выбранных столбцов, даже если мы используем отдельное ключевое слово для альбома, и мы используем другое столбцы it.still повторяют повторяющиеся данные. Как мы можем получить Данные однозначно - person Akshay Mukadam; 04.08.2014

используйте этот упрощенный код, чтобы получить список альбомов

public ArrayList<AlbumModel> getListOfAlbums(Context context) {

            String where = null;

            final Uri uri = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
            final String _id = MediaStore.Audio.Albums._ID;
            final String album_name = MediaStore.Audio.Albums.ALBUM;
            final String artist = MediaStore.Audio.Albums.ARTIST;
            final String albumart = MediaStore.Audio.Albums.ALBUM_ART;
            final String tracks = MediaStore.Audio.Albums.NUMBER_OF_SONGS;

            final String[] columns = { _id, album_name, artist, albumart, tracks };
            Cursor cursor = context.getContentResolver().query(uri, columns, where,
                    null, null);

            ArrayList<AlbumModel> list = new ArrayList<AlbumModel>();

            // add playlsit to list

            if (cursor.moveToFirst()) {

                do {

                    AlbumModel albumData = new AlbumModel();

                    albumData
                            .setAlbumID(cursor.getLong(cursor.getColumnIndex(_id)));

                    albumData.setAlbumName(cursor.getString(cursor
                            .getColumnIndex(album_name)));

                    albumData.setALbumArtist(cursor.getString(cursor
                            .getColumnIndex(artist)));

                    albumData.setAlbumArt(cursor.getString(cursor
                            .getColumnIndex(albumart)));

                    albumData.setTracks(cursor.getString(cursor
                            .getColumnIndex(tracks)));

                    list.add(albumData);

                } while (cursor.moveToNext());
            }

            cursor.close();

            return list;
        }
person Hitesh Sahu    schedule 17.01.2016

Это был исходный ответ

я отсортировал уникальные альбомы, проверив, не были ли они уже добавлены на мою карту

public Map<String, String> getAlbumList(Context c) {
    //setup map and cursor
    Map<String, String> result = new HashMap<String, String>();
    String selection = MediaStore.Audio.Media.IS_MUSIC + " !=0";
    final Cursor mCursor = c.getContentResolver().query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            new String[] {MediaStore.Audio.Media.ALBUM,
                    MediaStore.Audio.Media.ARTIST,
                    MediaStore.Audio.Media.ALBUM_ID,}, selection, null,
                   "LOWER ("+MediaStore.Audio.Media.ALBUM + ") ASC");

    int count = mCursor.getCount();


    String[] mArtist = new String[count];
    String[] mAlbum = new String[count];
    String[] AlbumID = new String[count];

    int i = 0;
    int j = 0;
    if (mCursor.moveToFirst()) {

        do {
            mAlbum[i] = mCursor
                    .getString(mCursor
                            .getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
            mArtist[i] = mCursor.getString(mCursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));

            AlbumID[i] = Long.toString(mCursor
                    .getLong(mCursor
                            .getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID)));

                                    //checking for same previous value
            if(result.containsValue(mAlbum[i])){

            }else{
            result.put("artist" + j, mArtist[i]);
            result.put("album" + j, mAlbum[i]);
            result.put("AlbumID" + j, AlbumID[i]);
            j = j + 1;
            }
            i = i + 1;

        } while (mCursor.moveToNext());
    }

    result.put("count", Integer.toString(j));
    mCursor.close();
    return result;
}
}

возможно, не самое красивое решение для уникальной сортировки альбомов... но оно работает именно так, как задумано, без возни с sqlite....

я передаю контекст здесь, потому что я использую список во фрагменте с настраиваемым адаптером без контекста активности, getContentResolver() не работает....

дополнение к исходному ответу

mArt, mData, mAlbums и mArtists — это списки массивов...

private void getList(View view){
    mArt.clear();
    mAlbums.clear();
    mArtists.clear();

    String[] projection = {"DISTINCT " + MediaStore.Audio.Media.ALBUM_ID,
            MediaStore.Audio.Media.ALBUM,
            MediaStore.Audio.Media.ARTIST

    } ;

    String[] projection2 = {"Distinct " + MediaStore.Audio.Albums.ALBUM,
    MediaStore.Audio.Albums.NUMBER_OF_SONGS};

    Cursor mCursor =  getActivity().getApplicationContext().getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, "0==0 ) GROUP BY (" + MediaStore.Audio.Media.ALBUM_ID, null, MediaStore.Audio.Media.ALBUM + " COLLATE NOCASE ASC");
    Cursor mCursor2 = getActivity().getApplicationContext().getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, projection2, null, null, MediaStore.Audio.Albums.ALBUM + " COLLATE NOCASE ASC");

    if(mCursor != null && mCursor.getCount() > 0 && mCursor2 != null && mCursor2.getCount() > 0){
        CursorJoiner joiner = new CursorJoiner(mCursor, new String[]{MediaStore.Audio.Media.ALBUM},mCursor2, new String[]{MediaStore.Audio.Albums.ALBUM});

        for (CursorJoiner.Result joinerResult : joiner) {
            switch (joinerResult) {
                case LEFT:
                    break;
                case RIGHT:
                    break;
                case BOTH:
                    String songs_s = "Song";
                    int tracks = mCursor2.getInt(mCursor2.getColumnIndex(MediaStore.Audio.Albums.NUMBER_OF_SONGS));
                    if (tracks > 1) {
                        songs_s = "Songs";
                    }
                    mArtists.add(tracks + " " + songs_s + " By " + mCursor.getString(mCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));
                    mAlbums.add(mCursor2.getString(mCursor2.getColumnIndex(MediaStore.Audio.Albums.ALBUM)));
                    mArt.add(ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), mCursor.getInt(mCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID))));

            }
        }
    }
    mCursor.close();
    mCursor2.close();
}

Предложение GROUP BY в выборе гарантирует уникальные альбомы, поскольку обложка альбома определяется идентификатором альбома в этой строке:

mArt.add(ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), mCursor.getInt(mCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID))));

следит за тем, чтобы обложка альбома и сам альбом находились в одном положении...

здесь я использую средство объединения курсоров, чтобы получить исполнителя, альбом и количество песен в альбоме... это можно вернуть только из двух отдельных запросов...

person me_    schedule 25.10.2013
comment
Сортирует ли этот код также идентификатор альбома, чтобы названия альбомов и обложки альбомов совпадали? У меня проблема в том, что я могу сортировать названия альбомов, и когда я хочу показать обложку альбома, она не соответствует названию альбома. Как я могу это решить? - person Vince VD; 30.06.2018
comment
Я получаю идентификатор альбома из MediaStore.Audio.Media.ALBUM_ID и использую этот идентификатор в picasso для отображения обложки. - person Vince VD; 30.06.2018
comment
У меня есть сообщение, в котором объясняется моя проблема stackoverflow.com/questions/51094052/ - person Vince VD; 30.06.2018
comment
@vince да, это так ... но после того, как я написал этот ответ, я нашел более простой способ сделать это ... я отредактирую ответ, чтобы отразить это ... - person me_; 01.07.2018
comment
второй блок кода возвращает три списка массивов: mArt с идентификатором обложки альбома, mAlbum с названием альбома и mArtist с именем исполнителя и количеством песен в альбоме в строке, подобной этой x Song(s) by Artist вам просто нужно знать положение любого из этих элементов, а все остальные находятся в одном и том же месте в соответствующих списках. - person me_; 01.07.2018
comment
@me_ я использую модель класса Song, где храню всю информацию. Могу ли я использовать это вместо массивов? как song.setArtist(tracks + + song_s + By + mCursor.getString(mCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST))); - person Vince VD; 01.07.2018
comment
@me_ не могли бы вы взглянуть на мой пост, там вы можете найти код, который я использую, чтобы получить исполнителя альбома и сам альбом. stackoverflow.com/questions/51094052 / Мне просто немного сложно реализовать ваш код в моем. - person Vince VD; 01.07.2018
comment
DISTINCT в проекции приводит к сбою приложения на Android 10 - person artman; 11.09.2019
comment
@artman нет ... я только что протестировал этот код на Android 10.0 (Q), API 29, версия 3. - person me_; 15.09.2019
comment
@me_ это странно, потому что у меня стабильный сбой на Pixel. - person artman; 16.09.2019