7

음악 플레이어의 재생 목록에 추가되는 ContentResolver을 사용하여 Playlist을 새로 만들려고하지만 코드가 실행되면 재생 목록에 삽입하면 null이 반환됩니다. Uri) 음악 플레이어의 재생 목록을 확인할 때 새로운 Playlist 항목이 없습니다. insert()이 null을 반환하는 이유는 정확하게 재생 목록을 만들지 않았기 때문입니다. 누군가 내 코드가 작동하지 않는다면 새로운 재생 목록을 동적으로 만드는 방법을 명확히 할 수 있습니까?ContentResolver를 사용하여 새 재생 목록을 만드는 방법

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가 ... (내 검색에서 나는 재생 목록을 조회하는 여러 가지 방법을 발견했지만, 아무것도 실제로 새로 생성하지 않음) 여기

내 코드의를 : 부분적으로 해결 **

위 코드는 4.0.3에 새 재생 목록을 올바르게 추가하지만 2.3에는 재생 목록을 올바르게 추가하지 않습니다. 4.0.3의 유일한 문제는 DATE_MODIFIED이 재생 목록에 설정되어 있고 재생 목록 항목에 PLAY_ORDER이 설정되어 있는지 확인해야한다는 것입니다.

나는 여전히 2.x에서의 재생 목록을 생성하지 왜 아무 생각이 없다, 그래서 누군가가 그것에 대한 어떤 생각을 가지고 있다면, 나는 알고 싶습니다.

답변

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 
}; 

올바른 열린 우리당 재생 목록 구성원을 추가 얻으려면, 당신은 ID가 필요합니다. 재생 목록에 노래를 추가하려면 재생 목록의 현재 상태에서 PLAYORDER의 현재 최고 표시를 알아야합니다. 그렇지 않으면 동일한 재생 순서로 재생 목록 멤버를 삽입하려고하기 때문에 MediaStore ContentResolver가 재생됩니다. 따라서 가장 높은 PLAYORDER 값을 얻으려면 먼저 재생 목록 Uri를 쿼리하여 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, 
}; 
+1

감사 @MarkG. 나는 결국이 일을 얻었다. 내 2.x 장치에서 작동하지 않는 이유는 miui가 실행 중이었기 때문입니다. miui이 표준 재생 목록 콘텐츠 제공 업체를 사용하지 않는 것 같습니다. 시아 노겐 모드로 장치를 다시 채웠을 때 모두 작동했습니다. – stuckless

+1

이 줄에서 앱이 다운 됨 mPlaylistId = c.getInt (c.getColumnIndex (MediaStore.Audio.Playlists._ID)); –

+1

은 신경 끄시 고 난 그냥 커서 C = mCR.query (MURI, PROJECTION_PLAYLIST, NULL, NULL, MediaStore.Audio.Playlists.DATE_MODIFIED)를 확인하기 위해, 내 자신의 필요에 따라 변경; if (c! = null) { \t c.moveToLast(); –

관련 문제