Как я могу сортировать альбомы по песням? - PullRequest
0 голосов
/ 29 июня 2018

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

Я попытался отсортировать идентификаторы альбомов, но это не исправило это, потому что идентификатор альбома не имеет ничего общего с сортировкой обложек.

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

Как мне отсортировать альбомы во фрагменте?

Ниже вы можете найти мой код.

Заранее спасибо,

Винс

МОДЕЛЬ ПЕСНИ

 // Columns I'll retrieve from the song table
    String[] columns = {
            SONG_ID,
            SONG_TITLE,
            SONG_ARTIST,
            SONG_ALBUM,
            SONG_ALBUMID,
            SONG_FILEPATH,
    };

    // Limits results to only show music files.
    //
    // It's a SQL "WHERE" clause - it becomes `WHERE IS_MUSIC=1`.
    //
    final String musicsOnly = MediaStore.Audio.Media.IS_MUSIC + "=1";

    // Querying the system
    cursor = resolver.query(musicUri, columns, musicsOnly, null, null);

    if (cursor != null && cursor.moveToFirst())
    {

        do {
            // Creating a song from the values on the row
            Song song = new Song(cursor.getInt(cursor.getColumnIndex(SONG_ID)),
                    cursor.getString(cursor.getColumnIndex(SONG_FILEPATH)));

            song.setTitle      (cursor.getString(cursor.getColumnIndex(SONG_TITLE)));
            song.setArtist     (cursor.getString(cursor.getColumnIndex(SONG_ARTIST)));
            song.setAlbumID    (cursor.getInt(cursor.getColumnIndexOrThrow(SONG_ALBUMID)));
            song.setAlbum      (cursor.getString(cursor.getColumnIndexOrThrow(SONG_ALBUM)));
            // Using the previously created genre and album maps
            // to fill the current song genre.
            String currentGenreID   = songIdToGenreIdMap.get(Long.toString(song.getId()));
            String currentGenreName = genreIdToGenreNameMap.get(currentGenreID);
            song.setGenre(currentGenreName);

            // Adding the song to the global list
            songs.add(song);
        }
        while (cursor.moveToNext());
    }
    else
    {
        // What do I do if I can't find any songs?

    }
    cursor.close();

public ArrayList<String> getArtists() {

    ArrayList<String> artists = new ArrayList<String>();

    for (Song song : songs) {
        String artist = song.getArtist();

        if ((artist != null) && (! artists.contains(artist)))
            artists.add(artist);
    }

    // Making them alphabetically sorted
    Collections.sort(artists, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.compareTo(o2);
        }
    });
    return artists;
}

/**
 * Returns an alphabetically sorted list with all the
 * albums of the scanned songs.
 *
 * @note This method might take a while depending on how
 *       many songs you have.
 */

public ArrayList<String> getAlbums() {

    ArrayList<String> albums = new ArrayList<String>();

    for (Song song : songs) {
        String album = song.getAlbum();

        if ((album != null) && (! albums.contains(album)))
            albums.add(album);

    }

ПЕСНОЙ КЛАСС

public class Song implements Serializable {

private long id;
private String data;
private String title = "";
private String artist = "";
private int   albumid      = -1;
private String album = "";
private String genre = "";


public Song(long songId, String songData){
    this.id = songId;
    this.data = songData;
}

public long getId(){
    return id;
}
public String getData(){return data;}

//Optional meta data

public void setTitle(String title){
    this.title = title;
}
public String getTitle() {
    return title;
}

public void setArtist(String artist){
    this.artist = artist;
}
public String getArtist() {
    return artist;
}

public int getAlbumID() {
    return albumid;
}
public void setAlbumID(int albumid) { this.albumid = albumid; }

public void  setAlbum(String album){
    this.album = album;
}
public String getAlbum() { return album; }

public void setGenre(String genre) {
    this.genre = genre;
}
public String getGenre() {
    return genre;
}


}

Ответы [ 5 ]

0 голосов
/ 02 июля 2018

Во-первых, я не уверен, почему вы пытаетесь отсортировать по альбомам, когда вы сохраняете возвращенные значения по песням (см. @Usman Rafi выше), но ..

Добавьте глобального массива в начало вашего фрагмента

ArrayList<Song> Albums = new Arraylist<>();

не пытайтесь добавлять информацию о жанре - она ​​вам не нужна для ваших целей

Я попытался отсортировать идентификаторы альбомов, но это не исправило это, потому что идентификатор альбома, очевидно, не имеет отношения к сортировке рисунков.

Обложка альбома Uri's может быть записана как:

ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"),
    cursor.getInt(cursor.getInt(cursor.getColumnIndexOrThrow(SONG_ALBUMID))));

Итак, обложка альбома и album_id на самом деле неразрывно связаны.

Так что моя проблема в том, что когда я пытаюсь отсортировать альбомы ...

Используйте MediaStore.Audio.Media.IS_MUSIC + "= 1) GROUP BY (" + MediaStore.Audio.Media.ALBUM в переменной выбора вашего запроса ...

При этом будут возвращены уникальные имена альбомов (также будет возвращена только одна песня в альбоме), если альбом повторяется (при наличии нескольких песен из одного альбома) в базе данных вашего медиастора, только первый экземпляр, который соответствует вашему запросу будет добавлен к вашему курсору.

для сортировки альбомов ...

Используйте порядок сортировки для сортировки строк курсора, возвращаемых альбомом; Я лично сортирую их, используя алфавитный порядок sql (символы, цифры, a, b, c ....)

Здесь следует отметить, что сортировка чувствительна к регистру, если вы не укажете "COLLATE NOCASE"

чтобы написать запрос и отсортировать его, я бы использовал следующий код:

String[] projection = {"DISTINCT " + MediaStore.Audio.Media.ALBUM_ID,
                         MediaStore.Audio.Media._ID, 
                         MediaStore.Audio.Media.TITLE, 
                         MediaStore.Audio.Media.ARTIST, 
                         MediaStore.Audio.Media.DATA, 
                         MediaStore.Audio.Media.ALBUM,
                         MediaStore.Audio.Media.IS_MUSIC};

String selection = MediaStore.Audio.Media.IS_MUSIC + 
                   "=1 ) GROUP BY (" + MediaStore.Audio.Media.ALBUM_ID;

String sort = MediaStore.Audio.Media.ALBUM + " COLLATE NOCASE ASC";

Cursor cursor = context.
                 getContentResolver().
                 query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
                 projection,
                 selection,
                 null,
                 sort);

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

Лично я просто перебираю

if(cursor != null && cursor.getCount >0){
    while(cursor.moveToNext()){
        //create new song item and add the album information you need
        Song album = new Song(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media._ID)),
           cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)));             

            album.setAlbumId(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)));
            album.setAlbumId(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)));

        //add the Song item to the global arraylist
        Albums.add(album)
    }
}

cursor.close();

теперь вы можете получить доступ к отсортированной информации об альбоме по позиции в массиве ... вы можете перейти к обложке альбома с помощью построителя Uri, который я показал вам сверху ...

вот так

Song Album = Albums.get(position);     
imageView.setURI(ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"),
    Album.getAlbumID());

Надеюсь, это вам пригодится.

я все еще думаю, что вы должны создать класс данных с именем Album

0 голосов
/ 29 июня 2018

Причина несовпадения 2, coverart и title заключается в том, что вы сортируете одно, а другое оставляете без изменений. Рассмотрим приведенный ниже пример:

Альбом перед сортировкой -

  1. Мир
  2. Hello

Идентификатор перед сортировкой 1 2

Альбом после сортировки 1. Привет 2. Мир

Но идентификатор остается таковым. Поэтому, когда вы строите URI для coverart, используя список идентификаторов, идентификатор, выбранный в позиции 0, соответствует альбому в позиции 1.

0 голосов
/ 29 июня 2018

Не внося значительных изменений в свой код, вы можете достичь того, что вы намереваетесь, отсортировав песни с помощью компаратора. Компаратор можно использовать всякий раз, когда вам нужно отсортировать объекты, используя одно из его свойств (в вашем случае это название альбома для объекта QuerySongs)

В вашем getAlbumsId методе добавьте следующее

public ArrayList<Long> getAlbumsId() {

    ArrayList<Long> albumids = new ArrayList<Long>();
    Collections.sort(songs, new Comparator<QuerySongs>() {
        @Override
        public int compare(QuerySongs o1, QuerySongs o2) {
            return o1.getAlbum().compareTo(o2.getAlbum());
        }
    });

    for (QuerySongs song : songs){
        Long albumid = song.getAlbumID();

        if (! albumids.contains(albumid)) {
            albumids.add(albumid);
        }
    }


    return albumids;
}

Выше будет мутировать объект songs, если вы не хотите, чтобы это произошло, сделайте его копию. Суть в том, чтобы использовать компаратор для сортировки песен.

0 голосов
/ 29 июня 2018

Прежде всего, вы должны создать класс Album , который содержит информацию об одном конкретном альбоме. Затем реализуйте Comparable или Comparator Interface.

  • Сравнимо , если альбомы всегда сортируются на основе одного и того же поле.
  • Компаратор , если вам нужно реализовать логику множественной сортировки
0 голосов
/ 29 июня 2018

Если я правильно понимаю ваш код, вы создаете список строк, который содержит альбомы, а затем сортируете этот список независимо от исходного списка песен Query. Это означает, что обложка альбома остается нетронутой. Я бы предложил использовать сопоставимый или компаратор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...