2012-06-10 18 views
7

Próbuję utworzyć nowy Playlist, używając Androida ContentResolver, który zostanie dodany do list odtwarzania odtwarzacza muzycznego, ale po uruchomieniu kodu wstawienie do listy odtwarzania zwróci wartość null (dla Uri) i kiedy sprawdzam listy odtwarzania odtwarzacza muzycznego, mój nowy wpis Playlist nie istnieje. Podejrzewam, że powodem, dla którego insert() zwraca wartość null, jest to, że nie utworzyłem poprawnie listy odtwarzania. Czy ktoś mógłby wyjaśnić, jak dynamicznie tworzyć nową listę odtwarzania, biorąc pod uwagę, że mój kod nie działa. (Z moich poszukiwań znalazłem kilka sposób do kwerendy list odtwarzania, ale nic właściwie tworzy nową)Tworzenie nowej listy odtwarzania przy użyciu ContentResolver

Oto mój kod ...

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: częściowo rozwiązany **

Powyższy kod poprawnie dodaje nową listę odtwarzania na 4.0.3, ale nie na 2.3. Jedynymi problematycznymi obszarami dla 4.0.3 było to, że musiałem się upewnić, że DATE_MODIFIED został ustawiony na liście odtwarzania i że PLAY_ORDER został ustawiony na liście odtwarzania.

Wciąż nie mam pojęcia, dlaczego nie utworzyłaby listy odtwarzania na 2.x, więc jeśli ktoś ma jakiekolwiek przemyślenia na ten temat, chciałbym wiedzieć.

Odpowiedz

8

Jest to kod używam w niestandardowy zbudowany AsyncTask i działa na 2.3, 3.1 i 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 
}; 

Aby uzyskać prawidłowe Uri dodać playlisty członków, trzeba Id. Aby dodać utwory do listy odtwarzania, musisz znać aktualny wysoki znak wodny PLAYORDER w bieżącym stanie listy odtwarzania. W przeciwnym razie MediaStore ContentResolver będzie gag, ponieważ próbujesz wstawić członków listy odtwarzania z tą samą kolejnością odtwarzania. Musisz więc najpierw zapytać Playlistę Uri, aby uzyskać najwyższą wartość PLAYORDER, i użyć jej jako punktu początkowego dla wstawek ContentValues.

Próbowałem tylko wstawić jeden element listy odtwarzania naraz, choć teoretycznie możesz mieć możliwość wstawiania zbiorczego. Poniższy kod jest skonfigurowany tak, aby w przyszłości konwertować na zbiorczy plik wstawiania, ale obecnie ma tylko jedną wstawkę naraz. Pobiera kursor utworów MediaStore.Audio.Media i wstawia je do ID listy odtwarzania, który został zapisany w 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

Dzięki @MarkG. W końcu udało mi się to osiągnąć. Wygląda na to, że powodem, dla którego nie działa on na moim urządzeniu 2.x, było uruchomienie miui. Domyślam się, że miui nie korzysta ze standardowego dostawcy treści na liście odtwarzania. Kiedy ponownie przymocowałem urządzenie modem cyjanu, wszystko działało. – stuckless

+1

Awaria aplikacji w tej linii mPlaylistId = c.getInt (c.getColumnIndex (MediaStore.Audio.Playlists._ID)); –

+1

nevermind i zmieniłem go zgodnie z moimi własnymi potrzebami, aby potwierdzić Kursor c = mCR.query (mUri, PROJECTION_PLAYLIST, null, null, MediaStore.Audio.Playlists.DATE_MODIFIED); if (c! = Null) { \t c.moveToLast(); –

Powiązane problemy