如何创建使用ContentResolver的一个新的播放列表 [英] How to create a new Playlist using ContentResolver

查看:159
本文介绍了如何创建使用ContentResolver的一个新的播放列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个新的播放列表,使用Android的 ContentResolver的,也将被添加到音乐播放器的播放列表,而code运行时,插入到播放列表中返回null(对于乌里),当我检查了音乐播放器的播放列表,我的新播放列表项是不存在的。我怀疑的原因,插入()返回null是因为我没有正确创建播放列表。可能有人阐明如何动态地创建新的播放列表,因为我的code不起作用。 (在我的搜索,我发现几个方法来查询的播放列表,但没有什么实际创建一个新的)

I'm attempting to create a new Playlist, using Android's ContentResolver, that will be added to music player's playlists, but when the code runs, the insert into the playlist returns null (for the Uri) and when I check the music player's playlists, my new Playlist entry isn't there. I suspect that the reason that the insert() returns null is because I haven't created the Playlist correctly. Could someone clarify how to dynamically create a new playlist, given that my code doesn't work. (In my searching, I've found several way to query playlists, but nothing actually creates a new one)

下面是我的code ...

Here's my code...

    ContentResolver resolver = getActivity().getContentResolver();

    Uri playlists = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;

    Log.d(A.TAG, "Checking for existing playlist for " + chart.getName());
    Cursor c = resolver.query(playlists, new String[] {"*"}, null, null, null);
    long playlistId = 0;
    c.moveToFirst();
    do {
        String plname = c.getString(c.getColumnIndex(MediaStore.Audio.Playlists.NAME));
        if (plname.equalsIgnoreCase(chart.getName())) {
            playlistId = c.getLong(c.getColumnIndex(MediaStore.Audio.Playlists._ID));
            break;
        }
    } while (c.moveToNext());
    c.close();

    if (playlistId!=0) {
        Uri deleteUri = ContentUris.withAppendedId(playlists, playlistId);
        Log.d(A.TAG, "REMOVING Existing Playlist: " + playlistId);

        // delete the playlist
        resolver.delete(deleteUri, null, null);
    }

    Log.d(A.TAG, "CREATING PLAYLIST: " + chart.getName());
    ContentValues v = new ContentValues();
    v.put(MediaStore.Audio.Playlists.NAME, chart.getName());
    v.put(MediaStore.Audio.Playlists.DATE_MODIFIED, System.currentTimeMillis());
    Uri newpl = resolver.insert(playlists, v);
    Log.d(A.TAG, "Added PlayLIst: " + newpl);

    Uri insUri = Uri.withAppendedPath(newpl, MediaStore.Audio.Playlists.Members.CONTENT_DIRECTORY);

    int order = 1;
    Log.d(A.TAG, "Playlist Members Url: " + insUri);
    c = getContentManager().queryWhere(getActivity(), Song.class, Song.Fields.LIBRARYID + " != 0 and " + Song.Fields.CHARTID + " = " + chart.getId(), (String[])null);
    if (c.moveToFirst()) {
        Log.d(A.TAG, "Adding Songs to PlayList **");
        do {
            long id = c.getLong(c.getColumnIndex(Song.Fields.LIBRARYID));
            ContentValues cv = new ContentValues();
            cv.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, order++);
            cv.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, id);
            Uri u = resolver.insert(insUri, cv);
            Log.d(A.TAG, "Added Playlist Item: " + u + " for AUDIO_ID " + id);
        } while (c.moveToNext());
    }
    c.close();

的更新:部分解决**

UPDATE: Partially Solved **

以上code不正确的添加一个新的播放列表 4.0.3 ,但不能在 2.3 。唯一的问题领域 4.0.3 是,我需要确保 DATE_MODIFIED 设置为播放列表,并且 PLAY_ORDER 设置为播放列表的项目。

The above code does correctly add a new Playlist on 4.0.3, but not on 2.3. The only problem areas for 4.0.3 was that I needed to make sure the DATE_MODIFIED was set on the Playlist and that PLAY_ORDER was set on the Playlist item.

我仍然不知道为什么它不会创建2.x的播放列表,因此,如果任何人有任何想法,我想知道。

I still have no idea why it would not create a playlist on 2.x, so if anyone has any thoughts on that, I'd like to know.

推荐答案

这是在code我在建AsyncTask的定制使用,它可以在2.3,3.1和4.03:

This is the code I use in a custom built AsyncTask and it works on 2.3, 3.1, and 4.03:

            ContentValues mInserts = new ContentValues();
            mInserts.put(MediaStore.Audio.Playlists.NAME, mPrefs.getString(AM.MEDIASTORECHANGE_NEWPLAYLISTNAME, "New Playlist"));
            mInserts.put(MediaStore.Audio.Playlists.DATE_ADDED, System.currentTimeMillis());
            mInserts.put(MediaStore.Audio.Playlists.DATE_MODIFIED, System.currentTimeMillis());
            mUri = mCR.insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, mInserts);
            if (mUri != null) {
                mPlaylistId = -1;
                mResult = FM.SUCCESS;
                c = mCR.query(mUri, PROJECTION_PLAYLIST, null, null, null);
                if (c != null) {
                    // Save the newly created ID so it can be selected.  Names are allowed to be duplicated,
                    // but IDs can never be.
                    mPlaylistId = c.getInt(c.getColumnIndex(MediaStore.Audio.Playlists._ID));
                    c.close();
                }
                if (DBG.AUDIO) {
                    Log.d(TAG, "PLAYLIST_ADD - mPlaylistId: " + mPlaylistId 
                            + "  mSelectString: " + mSelectString + "  mUri: "+ mUri.toString());
                }

            }

public static final String[] PROJECTION_PLAYLIST = new String[] {
    MediaStore.Audio.Playlists._ID,
    MediaStore.Audio.Playlists.NAME,
    MediaStore.Audio.Playlists.DATA
};

要获得正确的URI来添加播放列表中的成员,你需要的ID。将歌曲添加到播放列表中,你还需要知道在播放列表中的当前状态PLAYORDER目前的高水位。否则,MediaStore ContentResolver的会作呕,因为你要插入的播放列表成员相同的播放顺序。所以,你需要先查询该播放列表URI来获得最高的PLAYORDER值,并用它作为起点为您ContentValues​​插入。

To get the correct Uri to add playlist members, you need the Id. To add songs to the playlist, you also need to know the current high water mark of PLAYORDER in the playlist's current state. Otherwise the MediaStore ContentResolver will gag because you are trying to insert playlist members with the same play order. So, you need to query the Playlist Uri first to get the highest PLAYORDER value, and use that as the starting point for your ContentValues inserts.

我只是试图在同一时间插入一个播放列表成员,但在理论上你也许可以做一个批量插入。下面的code设置要转换为批量插入的未来,但是目前只做一个插入的时间。它需要一个光标MediaStore.Audio.Media歌曲并将其插入到已存储在共享preferences的播放列表ID。

I have only tried inserting one playlist member at a time, though in theory you might be able to do a bulk insert. The code below is set up to convert to a bulk insert in the future, but currently only does one insert at a time. It takes a cursor of MediaStore.Audio.Media songs and inserts them into a playlist Id that has been stored in SharedPreferences.

    private void addSongsInCursorToPlaylist(Cursor c) {
    int mIdCol;
    int mCount;
    int mPercent = 0;
    ContentResolver mCR = mContext.getContentResolver();
    ContentProviderClient mCRC = null;
    try {
        mCount = c.getCount();
        mIdCol = c.getColumnIndex(MediaStore.Audio.Media._ID);
        ContentValues[] mInsertList = new ContentValues[1];
        mInsertList[0] = new ContentValues();
        int mPlaylistId  = mPrefs.getInt(AM.PLAYLIST_NOWPLAYING_ID, AM.PLAYLIST_ID_DEFAULT);
        Uri mUri = MediaStore.Audio.Playlists.Members.getContentUri("external", mPlaylistId);
        Cursor c2 = mCR.query(mUri, 
                PROJECTION_PLAYLISTMEMBERS_PLAYORDER, null, null, MediaStore.Audio.Playlists.Members.PLAY_ORDER + " DESC ");
        int mPlayOrder = 1;
        if (c2 != null) {
            if (c2.moveToFirst()) {
                mPlayOrder = (c2.getInt(c2.getColumnIndex(MediaStore.Audio.Playlists.Members.PLAY_ORDER))) + 1;
            }
            c2.close();
        }
        mCRC = mCR.acquireContentProviderClient(mUri);
        if (DBG.AUDIO) {
            Log.d(TAG, "addSongsInCursorToPlaylist -Content Uri: " + mUri.toString() 
                    + "  PlaylistID: " + mPlaylistId + " mPlayOrder: " + mPlayOrder);
        }
        for (int i=0; i< mCount; i++) {
            if (c.moveToPosition(i)) {
                // Don't pollute with progress messages..has to be at least 1% increments
                int mTemp = (i * 100) / (mCount );
                if (mTemp > mPercent) {
                    mPercent = mTemp;
                    publishProgress(mPercent);
                }
                mInsertList[0].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, c.getLong(mIdCol));
                mInsertList[0].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, mPlayOrder++);
                mCR.insert(mUri, mInsertList[0]);
                if (DBG.AUDIO) {
                    Log.d(TAG, "addSongsInCursorToPlaylist -Adding AudioID: " + c.getLong(mIdCol) + " to Uri: " + mUri.toString()  );
                }
            }
            mCRC.release();
        }
    } catch (Throwable t) {
        t.printStackTrace();
    }

}
    // Projection to get high water mark of PLAY_ORDER in a particular playlist
public static final String[] PROJECTION_PLAYLISTMEMBERS_PLAYORDER = new String[] {
    MediaStore.Audio.Playlists.Members._ID,
    MediaStore.Audio.Playlists.Members.PLAY_ORDER
};
// Projection to get the list of song IDs to be added to a playlist
public static final String[] PROJECTION_SONGS_ADDTOPLAYLIST = new String[] {
    MediaStore.Audio.Media._ID,
};

这篇关于如何创建使用ContentResolver的一个新的播放列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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