Search code examples
androidmediaandroid-contentresolverplaylists

Android song ids different when retrieving from Playlists than when i'm retrieving from Media


I have 2 separate methods for retrieving songs using the content resolver. One i use to get all the songs on the phone and one i use to retrieve all playlists from my phone and then, for each playlist i get the songs on it and add it to the playlist object. I do this by searching through the list of all the songs for the ids that match the ids in the playlist. The problem is that the ids don't match. I know for sure for ex. that one playlist has 3 songs on it but the ids it finds are totally different from the one of the songs. This is the method i use for retrieving all the songs:

public ArrayList<Song> getSongList(){
        ArrayList<Song> songs = new ArrayList<Song>();
        //query external audio
        ContentResolver musicResolver = getContentResolver();
        Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
        //iterate over results if valid
        if(musicCursor!=null && musicCursor.moveToFirst()){
            //get columns
            int titleColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
            int idColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
            int artistColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.ARTIST);
            int albumColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.ALBUM);
            int durationColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.DURATION);
            int dataColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.DATA);
            int displayNameColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.DISPLAY_NAME);
            //add songs to list
            do {
                String name;
                if(musicCursor.getString(titleColumn)==null || musicCursor.getString(titleColumn).isEmpty()) name=musicCursor.getString(displayNameColumn);
                else name=musicCursor.getString(titleColumn);

                songs.add(new Song(musicCursor.getLong(idColumn), name, musicCursor.getString(albumColumn), musicCursor.getString(artistColumn), musicCursor.getString(durationColumn), musicCursor.getString(dataColumn)));


            } 
            while (musicCursor.moveToNext());
        }

And this is the one for playlists:

public void getPlayists() {
    playlists = new ArrayList<Playlist>();
    // query external audio
    String[] projection = {
            android.provider.MediaStore.Audio.Playlists._ID,
            android.provider.MediaStore.Audio.Playlists.NAME };

    String[] projectionPl = { 
            android.provider.MediaStore.Audio.Media._ID,
            android.provider.MediaStore.Audio.Media.TITLE };

    ContentResolver resolver = context.getContentResolver();

    Uri playlistsUri = android.provider.MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
    Cursor playlistsCursor = resolver.query(playlistsUri, projection, null,
            null, null);
    // iterate over results if valid
    if (playlistsCursor != null && playlistsCursor.moveToFirst()) {
        // get columns
        int idColumn = playlistsCursor
                .getColumnIndex(android.provider.MediaStore.Audio.Playlists._ID);
        int nameColumn = playlistsCursor
                .getColumnIndex(android.provider.MediaStore.Audio.Playlists.NAME);
        // add songs to list

        do {
            long id = playlistsCursor.getLong(idColumn);

            Playlist pl = new Playlist(
                    playlistsCursor.getString(nameColumn), id);

            Cursor plCursor = resolver.query(
                    android.provider.MediaStore.Audio.Playlists.Members
                            .getContentUri("external", id), projectionPl,
                    null, null, null);

            if (plCursor != null && plCursor.moveToFirst()) {
                // get columns
                int idColumna = plCursor
                        .getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
                int nameColumna = plCursor
                        .getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
                // add songs to list
                do {
                    long ida = plCursor.getLong(idColumna);

                    String title = plCursor.getString(nameColumna);

                    for (Song song : songs) {

                        if (song.id == ida) {
                            pl.addSong(song);
                        }
                    }

                } while (plCursor.moveToNext());
            }
            playlists.add(pl);

        } while (playlistsCursor.moveToNext());
    }

Can someone explain exactly how the song ids work or how can i modify my methods to make them work? Thanks.


Solution

  • Your playlistsCursor is against android.provider.MediaStore.Audio.Playlists.Members whereas you then proceed to get values from playlistsCursor but against android.provider.MediaStore.Audio.Media The returned structure for a playlist is:

            values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, playorder);
            values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, audio_id);
    

    so if you are looking for the audio Id then change

        int idColumn = playlistsCursor
                .getColumnIndex(android.provider.MediaStore.Audio.Playlists._ID);
    

    to

        int idColumn = playlistsCursor
                .getColumnIndex(MediaStore.Audio.Playlists.Members.AUDIO_ID);
    

    ps: I have previously posted code to create playlists etc. Look at my app Playlist Manager on Google Play or Amazon App Store for additional functionality