2012-06-10 17 views
7

Sto tentando di creare un nuovo Playlist, utilizzando Android ContentResolver, che verrà aggiunto alle playlist del lettore musicale, ma quando il codice viene eseguito, l'inserto nella playlist restituisce null (per il Uri) e quando controllo le playlist del lettore musicale, la mia nuova voce Playlist non è presente. Sospetto che il motivo per cui il numero insert() restituisce null è perché non ho creato correttamente la playlist. Qualcuno potrebbe chiarire come creare dinamicamente una nuova playlist, dato che il mio codice non funziona. (Nella mia ricerca, ho trovato diversi modo per interrogare le playlist, ma niente in realtà crea uno nuovo)Come creare una nuova playlist utilizzando ContentResolver

Ecco il mio codice ...

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: parzialmente risolto **

Il codice sopra riportato aggiunge correttamente una nuova playlist su 4.0.3, ma non su 2.3. Le uniche aree problematiche per 4.0.3 era che dovevo assicurarmi che il DATE_MODIFIED sia stato impostato sulla playlist e che PLAY_ORDER sia stato impostato sulla voce Playlist.

Non ho ancora idea del perché non creerebbe una playlist su 2.x, quindi se qualcuno ha qualche idea su questo, mi piacerebbe sapere.

risposta

8

Questo è il codice che uso in un AsyncTask personalizzato costruito e funziona su 2.3, 3.1 e 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 
}; 

Per ottenere il corretto Uri per aggiungere membri playlist, è necessario l'ID. Per aggiungere brani alla playlist, devi conoscere anche l'attuale limite massimo di PLAYORDER nello stato corrente della playlist. In caso contrario, MediaStore ContentResolver bloccherà perché si sta tentando di inserire i membri della playlist con lo stesso ordine di riproduzione. Pertanto, devi prima interrogare l'URI della playlist per ottenere il valore più alto di PLAYORDER e utilizzarlo come punto di partenza per gli inserimenti di ContentValues.

Ho solo provato a inserire un membro di playlist alla volta, anche se in teoria potresti essere in grado di eseguire un inserimento di massa. Il seguente codice è impostato per la conversione in un inserimento di massa in futuro, ma attualmente fa solo un inserto alla volta. Prende un cursore dei brani MediaStore.Audio.Media e li inserisce in un ID playlist che è stato memorizzato 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, 
}; 
+1

Grazie a @MarkG. Alla fine l'ho fatto funzionare. Sembra che il motivo per cui non funzionava sul mio dispositivo 2.x era che stava eseguendo miui. Suppongo che miui non stia utilizzando il provider di contenuti di playlist standard. Quando ho rifatto il dispositivo con il cyanogen mod, tutto ha funzionato. – stuckless

+1

arresto anomalo dell'app a questa riga mPlaylistId = c.getInt (c.getColumnIndex (MediaStore.Audio.Playlists._ID)); –

+1

non l'ho modificato in base alle mie esigenze, solo per confermare Cursore c = mCR.query (mUri, PROJECTION_PLAYLIST, null, null, MediaStore.Audio.Playlists.DATE_MODIFIED); if (c! = Null) { \t c.moveToLast(); –