So my problem is that when i try to sort the albums, the album title and album art are wrong.
I tried sorting the album ids but that doesn\'t fix it because album id hav
First, I'm not sure why you are trying to sort by album when you are storing your returned values by song (see @Usman Rafi above), but..
Add a global arraylist to the top of your fragment
ArrayList<Song> Albums = new Arraylist<>();
don't try to add genre information--you don't need it for your purpose
I tried sorting the album ids but that doesn't fix it because album id have nothing to do with sorting the art apparently.
Album art Uri's can be written as:
ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"),
cursor.getInt(cursor.getInt(cursor.getColumnIndexOrThrow(SONG_ALBUMID))));
So album art and album_id are actually inextricably linked.
So my problem is that when i try to sort the albums...
Use MediaStore.Audio.Media.IS_MUSIC + "=1 ) GROUP BY (" + MediaStore.Audio.Media.ALBUM in the selection variable of your query...
This will return unique album names (it will also only return one song within the album), if the album is repeated (by having several songs from the same album) in your mediastore database, only the first instance which matches your query will be added to your cursor.
to sort the albums...
Use the sort order to sort cursor rows which are returned by album; I personally sort them using sql's alphabetical order (symbols, numbers, a, b, c....)
You should note here that sorting is case sensitive unless you specify "COLLATE NOCASE"
to write your query and sort it I would use the following code:
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);
After this you can simply move through your cursor adding each row to the data object you built, there is no need for further sorting, and things should be in the proper order.
I personally just loop through
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();
you can now access the sorted album info by position in the arraylist... you can get to the album art using the Uri builder i showed you at the top...
like this
Song Album = Albums.get(position);
imageView.setURI(ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"),
Album.getAlbumID());
I hope this is useful to you.
i still think you should build a data class called Album
First of all, you should make a class Album that holds the information of one specific album. Then either implement Comparable or Comparator Interface.
The reason why the 2, coverart and title mismatch is because you sort one and leave out the other as is. Consider the below example :
Album before sort -
Id before sort- 1 2
Album after sort 1. Hello 2. World
But id remains as such. So when you build the uri for the coverart using the id list, id picked at position 0 is of album at position 1.
Without changing much in your code, you can achieve what you intend by sorting the Songs using a Comparator. Comparator can be used whenever you need to sort the objects using one of its properties (which is album name in your case for the QuerySongs
object)
In your getAlbumsId
method, add following
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;
}
Above will mutate the songs
object, if you don't want that to happend, make a copy of it. Crux is to use comparator to sort the songs.
If I understand your code correctly, you're creating a list of strings which contains albums, then sorting this list independent of the original Query songs list. This means the album art remains untouched. I'd suggest implementing a comparable or comparator.