¿Cómo continúan los reproductores de medios de Android la reproducción de canciones cuando se cierra la aplicación?

Se pregunta cómo se reproducirán las siguientes canciones una vez que la aplicación esté cerrada, como si estuviera reproduciendo un CD o una lista de reproducción completa …

El reproductor de medios sólo reproduce una pista de audio. Lo que hacen los reproductores de medios , es escuchar en el evento onCompletion y reproducir la siguiente pista.

El MediaPlayer está vinculado al proceso, no a la actividad, por lo que sigue jugando mientras el proceso se ejecuta. La actividad puede estar pausada o destruida, pero no afectará al hilo interno que utiliza MediaPlayer.

Estoy construyendo un reproductor de audio para aprender Android, puedes ver el servicio que reproduce archivos de audio aquí

editar

Con respecto al primer comentario: El servicio sigue funcionando en segundo plano y sigue funcionando después de que "salga" de la aplicación, porque el ciclo de vida del servicio y las actividades son diferentes.

Para reproducir la pista siguiente , el servicio registra una devolución de llamada en el MediaPlayer para que el servicio se informe cuando se completa una secuencia de audio. Cuando el audio se completa, el servicio limpia los recursos utilizados por MediaPlayer, llamando a MediaPlayer.release () y luego crea un nuevo reproductor de medios con la siguiente pista de audio para reproducir y se registra para ser notificado de nuevo cuando esa pista de audio Completa, ad infinitum :).

La clase MediaPlayer no entiende las listas de reproducción, por lo que el servicio es responsable de reproducir una pista después de completar la pista anterior.

En el servicio AudioPlayer que he creado, una actividad hace cola de pistas en AudioPlayer y el AudioPlayer es responsable de reproducirlas en orden.

Espero que esté claro y de nuevo, si tiene algún tiempo, por favor revise el código del servicio de AudioPlayer que he puesto arriba. No es pura belleza, pero hace su trabajo.

Puede crear un servicio para que MediaPlayer siga reproduciéndose después de que su aplicación salga o esté pausada. Para que MediaPlayer reproduzca pistas consecutivas, puede registrar un onCompletionListener que decidirá qué pista seguir. Aquí hay un ejemplo de servicio simple que hace esto:

package edu.gvsu.cis.muzak; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.net.Uri; import android.os.IBinder; import android.util.Log; public class MuzakService extends Service { private static final String DEBUG_TAG = "MuzakService"; private MediaPlayer mp; private String[] tracks = { "http://freedownloads.last.fm/download/288181172/Nocturne.mp3", "http://freedownloads.last.fm/download/367924875/Behemoths%2BSternentanz.mp3", "http://freedownloads.last.fm/download/185193341/Snowflake%2BImpromptu.mp3", "http://freedownloads.last.fm/download/305596593/Prel%25C3%25BAdio.mp3", "http://freedownloads.last.fm/download/142005075/Piano%2BSonata%2B22%2B-%2Bmovement%2B2%2B%2528Beethoven%2529.mp3", "http://freedownloads.last.fm/download/106179902/Piano%2BSonata%2B%25231%2B-%2Bmovement%2B%25234%2B%2528Brahms%2529.mp3", }; private int currentTrack = 0; @Override public void onCreate() { super.onCreate(); Log.d(DEBUG_TAG, "In onCreate."); try { Uri file = Uri.parse(tracks[this.currentTrack]); mp = new MediaPlayer(); mp.setDataSource(this, file); mp.prepare(); mp.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { currentTrack = (currentTrack + 1) % tracks.length; Uri nextTrack = Uri.parse(tracks[currentTrack]); try { mp.setDataSource(MuzakService.this,nextTrack); mp.prepare(); mp.start(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } catch (Exception e) { Log.e(DEBUG_TAG, "Player failed", e); } } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.d(DEBUG_TAG, "In onDestroy."); if(mp != null) { mp.stop(); } } @Override public int onStartCommand(Intent intent,int flags, int startId) { super.onStart(intent, startId); Log.d(DEBUG_TAG, "In onStart."); mp.start(); return Service.START_STICKY_COMPATIBILITY; } @Override public IBinder onBind(Intent intent) { Log.d(DEBUG_TAG, "In onBind with intent=" + intent.getAction()); return null; } } 

Puede iniciar este servicio en una actividad de la siguiente manera:

 Intent serv = new Intent(this,MuzakService.class); startService(serv); 

Y detenerlo así:

 Intent serv = new Intent(this,MuzakService.class); stopService(serv); 

El reproductor de mediap debe funcionar del servicio, aquí he pasado el arraylist de canciones de la actividad al servicio y todas las canciones son funcionadas leyendo el arraylist

Public class MyService extends Service implementa OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {

 Context context; private static final String ACTION_PLAY = "PLAY"; private static final String TAG = "SONG SERVICE"; MediaPlayer mediaPlayer; private int currentTrack = 0; ArrayList<String> list; public MyService() { context=getBaseContext(); } @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { list = (ArrayList<String>)intent.getSerializableExtra("arraylist"); int count=0; Log.d(TAG, "total count:"+list.size()); //playing song one by one for (String string : list) { //play(string); count++; Log.d(TAG, "count:"+list); } play(currentTrack); Log.d(TAG, "count:"+count); if(count==list.size()){ //stopSelf(); Log.d(TAG, "stoping service"); //mediaPlayer.setOnCompletionListener(this); }else{ Log.d(TAG, "not stoping service"); } if (!mediaPlayer.isPlaying()) { mediaPlayer.start(); Log.d(TAG, "oncommat"); } return START_STICKY; } @Override public void onCreate() { Toast.makeText(this, "Service was Created", Toast.LENGTH_LONG).show(); } @Override public void onStart(Intent intent, int startId) { // Perform your long running operations here. Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show(); } @Override public void onDestroy() { Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show(); Log.d("service", "destroyed"); if (mediaPlayer.isPlaying()) { mediaPlayer.stop(); } mediaPlayer.release(); } @Override public boolean onError(MediaPlayer mp, int what, int extra) { // TODO Auto-generated method stub return false; } @Override public void onPrepared(MediaPlayer mp) { // TODO Auto-generated method stub } private void play(int id) { if(mediaPlayer!=null && mediaPlayer.isPlaying()){ Log.d("*****begin*****", "playing"); stopPlaying(); Log.d("*****begin*****", "stoping"); } else{ Log.d("*****begin*****", "nothing"); } Log.d("*****play count*****", "="+currentTrack); Log.i("******playing", list.get(currentTrack)); Uri myUri1 = Uri.parse(list.get(id)); mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); //mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK); mediaPlayer.setOnPreparedListener(this); //mediaPlayer.setOnCompletionListener(this); mediaPlayer.setOnErrorListener(this); try { mediaPlayer.setDataSource(context, myUri1); Log.i("******playing", myUri1.getPath()); } catch (IllegalArgumentException e) { Toast.makeText(context, "You might not set the URI correctly!", Toast.LENGTH_LONG).show(); } catch (SecurityException e) { Toast.makeText(context, "You might not set the URI correctly!", Toast.LENGTH_LONG).show(); } catch (IllegalStateException e) { Toast.makeText(context, "You might not set the URI correctly!", Toast.LENGTH_LONG).show(); } catch (IOException e) { e.printStackTrace(); } try { mediaPlayer.prepare(); } catch (IllegalStateException e) { Toast.makeText(context, "You might not set the URI correctly!", Toast.LENGTH_LONG).show(); } catch (IOException e) { Toast.makeText(context, "You might not set the URI correctly!", Toast.LENGTH_LONG).show(); } mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { currentTrack=currentTrack+1; play(currentTrack); /* currentTrack = (currentTrack + 1) % list.size(); Uri nextTrack=Uri.parse(list.get(currentTrack)); try { mediaPlayer.setDataSource(context,nextTrack); mediaPlayer.prepare(); // mediaPlayer.start(); } catch (Exception e) { e.printStackTrace(); }*/ } }); mediaPlayer.start(); } private void stopPlaying() { if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } } @Override public void onCompletion(MediaPlayer mp) { // TODO Auto-generated method stub } 

La respuesta es Servicios en Android como se describe aquí: http://developer.android.com/guide/topics/fundamentals.html como

Vas a crear un servicio y cuando recibas el comando de reproducción de tu aplicación, tu aplicación enviará un mensaje al servicio de fondo para reproducir la música. Los servicios no se ejecutan en primer plano, por lo tanto, incluso se pone la pantalla para dormir, se reproduce la música.

Reproducción de música BG en actividades en Android

Observe por favor que el servicio funciona en suelo delantero también.

Consulte la documentación oficial. Se explica con un código de ejemplo. Uso de un servicio con MediaPlayer: http://developer.android.com/guide/topics/media/mediaplayer.html#mpandservices

Funcionando como un servicio de primer plano

Los servicios se utilizan a menudo para realizar tareas de fondo

Pero considere el caso de un servicio que está tocando música. Claramente este es un servicio que el usuario está activamente consciente y la experiencia se vería seriamente afectada por cualquier interrupción. Además, es un servicio al que el usuario probablemente deseará interactuar durante su ejecución. En este caso, el servicio debe ejecutarse como un "servicio de primer plano". Un servicio de primer plano tiene un mayor nivel de importancia dentro del sistema; el sistema casi nunca matará el servicio, porque es de importancia inmediata para el usuario. Cuando se ejecuta en primer plano, el servicio también debe proporcionar una notificación de barra de estado para asegurarse de que los usuarios son conscientes del servicio en ejecución y permitirles abrir una actividad que puede interactuar con el servicio.

Para convertir su servicio en un servicio de primer plano, debe crear una notificación para la barra de estado y llamar a startForeground () desde el servicio

  • ¿Cómo puedo reproducir un flujo de audio HTTP en directo en MediaPlayer en Android?
  • ¿Determinar la estructura de opencore o stagefright para mediaplayer?
  • Problemas de almacenamiento intermedio con android.media.MediaPlayer
  • ¿Cómo reanudar el reproductor multimedia?
  • Android - Múltiple, transmisión simultánea de audio
  • ¿Qué significa MediaPlayer info / warning (973, 0)?
  • Detener / liberar Mediaplayer en onDestory () hace que NullPointerException
  • Cómo jugar a la radio en vivo .asx video / x-ms-asf?
  • Problemas con MediaPlayer, recursos crudos, detener e iniciar
  • MediaPlayer error -2147483648 al reproducir archivos en almacenamiento interno
  • ¿Por qué mediaPlayer.seekTo (msec) no actualiza surfaceView cuando mediaPlayer está pausado?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.