7

Estoy intentando crear una nueva Playlist, usando Android ContentResolver, que se agregará a las listas de reproducción del reproductor de música, pero cuando se ejecuta el código, la inserción en la lista de reproducción devuelve nulo (para el Uri) y cuando reviso las listas de reproducción del reproductor de música, mi nueva entrada Playlist no está allí. Sospecho que la razón por la que el insert() devuelve null es porque no he creado la lista de reproducción correctamente. ¿Podría alguien aclarar cómo crear dinámicamente una nueva lista de reproducción, dado que mi código no funciona? (En mi búsqueda, he encontrado varios forma de consultar las listas de reproducción, pero nada realmente crea una nueva)Cómo crear una nueva lista de reproducción usando ContentResolver

es mi código aquí ...

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

ACTUALIZACIÓN: Parcialmente Resuelto **

El código anterior agrega correctamente una nueva lista de reproducción en 4.0.3, pero no en 2.3. Las únicas áreas problemáticas para 4.0.3 era que necesitaba asegurarme de que el DATE_MODIFIED estaba configurado en la lista de reproducción y que PLAY_ORDER estaba configurado en el elemento Playlist.

Todavía no tengo idea de por qué no crearía una lista de reproducción en 2.x, así que si alguien tiene alguna idea al respecto, me gustaría saberlo.

Respuesta

8

Este es el código que utilizo en un AsyncTask hecha a la medida y funciona en 2.3, 3.1 y 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 
}; 

Para obtener el URI correcto para añadir miembros de lista de reproducción, se necesita el Id. Para agregar canciones a la lista de reproducción, también necesita conocer la marca de agua máxima actual de PLAYORDER en el estado actual de la lista de reproducción. De lo contrario, MediaStore ContentResolver se morderá porque está intentando insertar miembros de la lista de reproducción con el mismo orden de reproducción. Por lo tanto, primero debe consultar la lista de reproducción Uri para obtener el valor más alto de PLAYORDER y utilizarlo como punto de partida para sus inserciones de ContentValues.

Solo he intentado insertar un miembro de la lista de reproducción a la vez, aunque en teoría es posible que pueda hacer una inserción masiva. El código siguiente está configurado para convertirse en una inserción masiva en el futuro, pero actualmente solo se inserta una a la vez. Toma un cursor de las canciones de MediaStore.Audio.Media y las inserta en una ID de la lista de reproducción que se ha almacenado en 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

Gracias @MarkG. Eventualmente logré que esto funcionara. Parece que la razón por la que no funcionaba en mi dispositivo 2.x era que estaba ejecutando miui. Supongo que miui no está usando el proveedor de contenido de lista de reproducción estándar. Cuando reinvirtí el dispositivo con mod de cianógeno, todo funcionó. – stuckless

+1

aplicación que se bloquea en esta línea mPlaylistId = c.getInt (c.getColumnIndex (MediaStore.Audio.Playlists._ID)); –

+1

Nunca lo cambié de acuerdo a mis propias necesidades, solo para confirmar Cursor c = mCR.query (mUri, PROJECTION_PLAYLIST, null, null, MediaStore.Audio.Playlists.DATE_MODIFIED); if (c! = Null) { \t c.moveToLast(); –

Cuestiones relacionadas