6

Sto correndo in un roadblock integrando musica nella mia app per Android. L'obiettivo è far vedere agli utenti & riprodurre brani a cui hanno già accesso, tramite Google Play Music (o qualsiasi altro player come Winamp, Poweramp, doubleTwist, ecc.).Come consentire agli utenti di visualizzare e riprodurre brani su Android a cui hanno già accesso (ad es. Tramite Google Play)?

Finora, ho provato un paio di approcci, ma ognuno ha problemi.

Approccio # 1: Utilizzare una query ContentResolver per ottenere playlist & canzoni da Google Play Music, poi giocare con MediaPlayer

primo luogo, ottenere un cursore sulle liste di riproduzione:

String[] proj = { MediaStore.Audio.Playlists.NAME, 
        MediaStore.Audio.Playlists._ID }; 
Uri playlistUri = Uri.parse("content://com.google.android.music.MusicContent/playlists"); 
Cursor playlistCursor = getContentResolver().query(playlistUri, proj, null, null, null); 

Poi iterare per ottenere le canzoni in ogni playlist, e leggerli in questo modo:

String[] proj2 = { MediaStore.Audio.Playlists.Members.TITLE, 
        MediaStore.Audio.Playlists.Members._ID }; 
String playListRef = "content://com.google.android.music.MusicContent/playlists/" + playListId + "/members"; 
Uri songUri = Uri.parse(playListRef); 
Cursor songCursor = getContentResolver().query(songUri, proj2, null, null, null); 

questo wor per ottenere playlist e brani, ma in questo caso non è possibile riprodurli (anche se comunichi a Google Play Music "Keep on device"). In particolare, il seguente codice non gioca un determinato brano trovato come sopra:

mediaPlayer = new MediaPlayer(); 
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
try { 
    mediaPlayer.setDataSource(dataPath); 
    mediaPlayer.prepare(); 
    mediaPlayer.start(); 
} catch (Exception e) {} 

In realtà, ho scannerizzato il dispositivo, e non sono stato in grado di trovare i file ovunque (anche se ho hanno confermato sono locali disabilitando completamente la rete - sia su Galaxy Nexus che su Galaxy S3).

Approccio # 2: Invocate Google Play Music, o altro lettore, utilizzando un Intent

Secondo this post, si può semplicemente richiamare il lettore utilizzando Intenti, in questo modo:

Intent intent = new Intent(); 
intent.setAction(android.content.Intent.ACTION_VIEW); 
File file = new File(YOUR_SONG_URI); 
intent.setDataAndType(Uri.fromFile(file), "audio/*"); 
startActivity(intent); 

Ma Non penso che questo approccio consenta alcun tipo di controllo, ad esempio il passaggio di una canzone specifica da riprodurre o la notifica di quando una canzone viene eseguita. Inoltre, @CommonWares sottolinea che l'app musicale e i suoi Intenti non fanno parte dell'API pubblica dell'SDK di Android e potrebbero essere modificati senza preavviso.

La funzionalità di base che sto cercando di ottenere esiste in iOS, grazie alla stretta integrazione con iTunes. Penserei che Google vorrebbe ottenere lo stesso tipo di integrazione, dal momento che potrebbe significare vendere molta più musica nel Play Store.

In sintesi: È possibile consentire agli utenti di vedere & riprodurre brani a cui hanno già accesso su Android? Qual è il modo migliore per farlo con Google Play Music o qualsiasi altra app? Grazie.

+1

UPDATE: finché non trovo una buona risposta per l'integrazione con Google Play Music o di un altro lettore di musica, ho appena sviluppato un'interfaccia che legge e riproduce file musicali memorizzati in locale sul dispositivo (utilizzando una query per trovare ContentResolver le canzoni e MediaPlayer per riprodurle). Questo sembra funzionare bene, ma lascia all'utente la possibilità di spostare file mp3 e altri file musicali sul dispositivo. Preferirei comunque trovare una soluzione che renda facile per tutti fornendo una buona integrazione con un lettore musicale popolare .... Chiunque? – gcl1

+0

Penso che il tuo approccio # 1 dovrebbe funzionare se ottieni l'url di streaming corrispondente alla traccia selezionata e lo passi a MediaPlayer. –

+0

L'ultima volta che ho provato a dicembre, non ero in grado di far funzionare l'approccio n. 1. Ma sarei molto interessato a sapere se lo hai effettivamente fatto. Nel frattempo, come ho detto nel commento UPDATE, sto semplicemente lasciando che gli utenti riproducano musica che è memorizzata localmente sul dispositivo. Grazie. – gcl1

risposta

1

L'approccio numero 1 funziona (testato con musica locale sul dispositivo), grazie OP per la direzione.

Note:

  • Stiamo giocando con un'API interna non documentato qui - non è affidabile.
  • Non ho accesso a musica online/acquistata su Google Riproduci musica, quindi la risposta si riferisce solo alla musica memorizzata localmente.

Il codice seguente verrà iterato su tutti i brani in una playlist e riprodurrà l'ultimo.

Nota la colonna "SourceId" - è l'ID audio che utilizzeresti come da documentation. L'ho trovato iterando su tutte le colonne restituite dal cursore. Ci sono molte altre colonne interessanti, come "hasLocal", "hasRemote" che potrebbero (o non) riferirsi a dove è memorizzata la musica.

String[] proj2 = { "SourceId", MediaStore.Audio.Playlists.Members.TITLE, MediaStore.Audio.Playlists.Members._ID }; 
String playListRef = "content://com.google.android.music.MusicContent/playlists/" + playListId + "/members"; 
Uri songUri = Uri.parse(playListRef); 
Cursor songCursor = getContentResolver().query(songUri, proj2, null, null, null); 

long audioId = -1; 
while (songCursor.moveToNext()) { 
    audioId = songCursor.getLong(songCursor.getColumnIndex("SourceId")); 
    String title = songCursor.getString(songCursor.getColumnIndex(MediaStore.Audio.Playlists.Members.TITLE)); 
    Log.v("", "audioId: " + audioId + ", title: " + title); 
} 
songCursor.close(); 

MediaPlayer mpObject = new MediaPlayer(); 
try { 
    if (audioId > 0) { 
     Uri contentUri = ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, Long.valueOf(audioId)); 
     mpObject.setAudioStreamType(AudioManager.STREAM_MUSIC); 
     mpObject.setDataSource(this, contentUri); 
     mpObject.prepare(); 
     mpObject.start(); 

    } 
} catch (Exception e) { 
    e.printStackTrace(); 
}