如何从歌曲中分类专辑? [英] How can i sort albums from songs?

查看:146
本文介绍了如何从歌曲中分类专辑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我的问题是,当我尝试对专辑进行排序时,专辑标题和专辑封面都是错误的。



我尝试对专辑ID进行排序,但这并不是'修复它,因为专辑ID与艺术品的排序无关。



当我遗漏排序时,一切都是正确的,但是当我尝试对它们进行排序时名称与专辑封面不符。



如何在片段中对我的专辑进行排序?



下面在这里你可以找到我的代码。



提前致谢,



Vince



SONG MODEL

  //我将从歌曲中检索的列table 
String [] columns = {
SONG_ID,
SONG_TITLE,
SONG_ARTIST,
SONG_ALBUM,
SONG_ALBUMID,
SONG_FILEPATH,
};

//限制结果仅显示音乐文件。
//
//这是一个SQLWHERE子句 - 它变为`WHERE IS_MUSIC = 1`。
//
final String musicsOnly = MediaStore.Audio.Media.IS_MUSIC += 1;

//查询系统
cursor = resolver.query(musicUri,columns,musicsOnly,null,null);

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

do {
//创建一首歌来自行上的值
歌曲=新歌曲(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)));
//使用先前创建的流派和专辑地图
//来填充当前的歌曲类型。
String currentGenreID = songIdToGenreIdMap.get(Long.toString(song.getId()));
String currentGenreName = genreIdToGenreNameMap.get(currentGenreID);
song.setGenre(currentGenreName);

//将歌曲添加到全局列表
songs.add(song);
}
while(cursor.moveToNext());
}
else
{
//如果找不到任何歌曲怎么办?

}
cursor.close();

public ArrayList< String> getArtists(){

ArrayList< String> artists = new ArrayList< String>(); (歌曲:歌曲)

{
String artist = song.getArtist();

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

//按字母顺序排序
Collections.sort(艺术家,新Comparator< String>(){
@Override
public int compare (String o1,String o2){
return o1.compareTo(o2);
}
});
返回艺术家;
}

/ **
*返回按字母顺序排序的列表,其中包含扫描歌曲的所有
*专辑。
*
* @note此方法可能需要一段时间,具体取决于
*您拥有多首歌曲的方式。
* /

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);

}

SONG CLASS

 公共类歌曲实现Serializable {

private long id;
私有字符串数据;
private String title =;
private String artist =;
private int albumid = -1;
private String album =;
private String genre =;


公共歌曲(long songId,String songData){
this.id = songId;
this.data = songData;
}

public long getId(){
return id;
}
public String getData(){return 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;
}


}


解决方案

首先,我不确定为什么你在按歌曲存储你的返回值时试图按专辑排序(参见上面的@Usman Rafi),但是..



在片段顶部添加全局字幕搜索

  ArrayList<曲>专辑=新的Arraylist<>(); 

不要尝试添加类型信息 - 您不需要它目的


我尝试对专辑ID进行排序,但这并不能解决问题,因为专辑ID与排序无关艺术显然。


专辑艺术Uri可以写成:

  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<,否则排序区分大小写/ p>

编写查询并对其进行排序我将使用以下代码:

  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};

字符串选择= MediaStore.Audio.Media.IS_MUSIC +
= 1)GROUP BY(+ MediaStore.Audio.Media.ALBUM_ID;

字符串排序= MediaStore.Audio.Media.ALBUM +COLLATE NOCASE ASC;

Cursor cursor = context。
getContentResolver()。
query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
预测,
选择,
null,
排序);

在此之后你可以简单地移动光标,将每一行添加到你构建的数据对象中,不需要进一步排序,并且事情应该按照正确的顺序进行。



我个人只是循环遍历

  if(cursor!= null&& cursor.getCount> 0 ){
while(cursor.moveToNext()){
//创建新歌曲项目并添加你需要的专辑信息
歌曲专辑=新歌曲(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)));

//将歌曲项添加到全局arraylist
Albums.add(专辑)
}
}

cursor.close( );

您现在可以按照arraylist中的位置访问已排序的相册信息...您可以访问使用Uri构建器的专辑封面我在顶部向您展示...



喜欢这样

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

我希望这对你有用。



我仍然认为你应该建立一个名为Album的数据类


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 have nothing to do with sorting the art apparently.

When i leave out the sorting everything is correct, but when i try to sort them the album names don't match the album art.

How can i sort my albums in the fragment?

Beneath here you can find my code.

Thanks in advance,

Vince

SONG MODEL

 // 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);

    }

SONG CLASS

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;
}


}

解决方案

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

这篇关于如何从歌曲中分类专辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆