我正在尝试使用Android的Playlist
创建一个新的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();
更新:部分解决**
上述代码确实在4.0.3
上添加了新的播放列表,但未在2.3
上添加。 4.0.3
的唯一问题是我需要确保在播放列表中设置了DATE_MODIFIED
并且在播放列表项目上设置了PLAY_ORDER
。
我仍然不知道为什么它不会在2.x上创建播放列表,所以如果有人对此有任何想法,我想知道。
答案 0 :(得分: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,
};