7

我正在尝试Playlist使用 Android 创建一个新的ContentResolver,它将添加到音乐播放器的播放列表中,但是当代码运行时,插入到播放列表中返回 null (对于Uri),当我检查音乐播放器的播放列表时,我的新Playlist条目不在那里。我怀疑insert()返回 null 的原因是因为我没有正确创建播放列表。鉴于我的代码不起作用,有人可以澄清如何动态创建新的播放列表。(在我的搜索中,我找到了几种查询播放列表的方法,但实际上并没有创建新的方法)

这是我的代码...

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

更新:部分解决**

上面的代码确实正确地添加了一个新的播放列表 on 4.0.3,但不是 on 2.3。唯一的问题区域4.0.3是我需要确保DATE_MODIFIED已在播放列表中PLAY_ORDER设置并且已在播放列表项中设置。

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

4

1 回答 1

8

这是我在自定义构建的 AsyncTask 中使用的代码,它适用于 2.3、3.1 和 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 插入的起点。

我只尝试一次插入一个播放列表成员,但理论上您可能可以进行批量插入。下面的代码设置为将来转换为批量插入,但目前一次只插入一个。它采用 MediaStore.Audio.Media 歌曲的光标并将它们插入到已存储在 SharedPreferences 中的播放列表 ID 中。

    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,
};
于 2012-07-18T15:14:32.427 回答