2012-06-10 22 views
7

Tôi đang cố gắng tạo Playlist mới bằng Android ContentResolver, sẽ được thêm vào danh sách phát của trình phát nhạc, nhưng khi mã chạy, chèn vào danh sách phát sẽ trả về giá trị rỗng (cho Uri) và khi tôi kiểm tra danh sách phát của trình phát nhạc, mục nhập Playlist mới của tôi không có ở đó. Tôi nghi ngờ rằng lý do mà insert() trả về null là vì tôi chưa tạo Danh sách phát một cách chính xác. Ai đó có thể làm rõ cách tạo động danh sách phát mới, vì mã của tôi không hoạt động. (Trong tìm kiếm của tôi, tôi đã tìm thấy một số cách để truy vấn danh sách nhạc, nhưng không thực sự tạo ra một cái mới)Cách tạo Danh sách phát mới bằng ContentResolver

Dưới đây là mã của tôi ...

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

CẬP NHẬT: Một phần Giải Quyết **

Mã ở trên không thêm chính xác Danh sách phát mới trên 4.0.3, nhưng không phải trên 2.3. Các vùng sự cố duy nhất cho 4.0.3 là tôi cần đảm bảo rằng DATE_MODIFIED được đặt trên Danh sách phát và PLAY_ORDER được đặt trên mục Danh sách phát.

Tôi vẫn không biết tại sao nó sẽ không tạo danh sách phát trên 2.x, vì vậy nếu có ai có bất kỳ suy nghĩ nào về điều đó, tôi muốn biết.

Trả lời

8

Đây là mã tôi sử dụng trong một AsyncTask xây dựng tùy chỉnh và nó hoạt động trên 2.3, 3.1, và 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 
}; 

Để có được đúng Uri để thêm thành viên playlist, bạn cần Id. Để thêm bài hát vào danh sách phát, bạn cũng cần biết điểm đánh dấu nước cao hiện tại của PLAYORDER trong trạng thái hiện tại của danh sách phát. Nếu không, MediaStore ContentResolver sẽ gag vì bạn đang cố chèn thành viên danh sách phát có cùng thứ tự phát. Vì vậy, bạn cần phải truy vấn Uri Playlist trước để nhận giá trị PLAYORDER cao nhất và sử dụng điểm đó làm điểm bắt đầu cho chèn nội dung của bạn.

Tôi chỉ cố gắng chèn một thành viên danh sách phát tại một thời điểm, mặc dù trên lý thuyết bạn có thể thực hiện chèn hàng loạt. Mã bên dưới được thiết lập để chuyển đổi thành chèn hàng loạt trong tương lai, nhưng hiện tại chỉ có một lần chèn vào một lần. Nó có một con trỏ của các bài hát MediaStore.Audio.Media và chèn chúng vào một Id danh sách phát đã được lưu trữ trong 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, 
}; 
+1

Cảm ơn @MarkG. Cuối cùng tôi đã làm việc này. Có vẻ như lý do tại sao nó không hoạt động trên thiết bị 2.x của tôi là nó đang chạy miui. Tôi đoán miui không sử dụng nhà cung cấp nội dung danh sách phát chuẩn. Khi tôi reflashed thiết bị với mod Cyanogen, tất cả đều hoạt động. – stuckless

+1

lỗi ứng dụng tại dòng này mPlaylistId = c.getInt (c.getColumnIndex (MediaStore.Audio.Playlists._ID)); –

+1

nevermind i thay đổi nó theo nhu cầu của riêng tôi, chỉ để xác nhận Con trỏ c = mCR.query (mUri, PROJECTION_PLAYLIST, null, null, MediaStore.Audio.Playlists.DATE_MODIFIED); nếu (c! = Null) { \t c.moveToLast(); –

Các vấn đề liên quan