Crear un reproductor de música en Android controles de usuario

Estamos construyendo una aplicación de reproductor de música simple para Android en esta serie. Hasta ahora, hemos presentado una lista de las canciones en el dispositivo y hemos permitido al usuario realizar selecciones desde el mismo, comenzando la reproducción con la tecla Reproductor multimedia clase en un Servicio clase. En esta parte final de la serie, permitiremos que el usuario controle la reproducción, lo que incluye saltar a las pistas siguientes y anteriores, avanzar rápidamente, rebobinar, reproducir, pausar y buscar puntos específicos en la pista. También mostraremos una notificación durante la reproducción para que el usuario pueda volver al reproductor de música después de usar otras aplicaciones..

Buscando un atajo?

Esta serie de tutoriales lo lleva a través del proceso de creación de una aplicación de reproductor de música desde cero. Si desea una solución ya hecha, pruebe Android Music Player, un reproductor de música avanzado para dispositivos Android. Le permite navegar y reproducir su música por álbumes, artistas, canciones, listas de reproducción, carpetas y artistas de álbumes, y tiene una gama de otras características.

Reproductor de musica android

O si quieres algo completamente personalizado a tus especificaciones, puedes contratar a un desarrollador de Android en Envato Studio para hacer cualquier cosa, desde ajustes y correcciones de errores hasta crear una aplicación completa desde cero..

Introducción

La funcionalidad de control del reproductor de música se implementará utilizando el MediaController clase, en la que un Barra de busqueda La instancia muestra el progreso de la reproducción y permite que el usuario salte a ubicaciones particulares en una pista. Usaremos el Notificación y PendingIntent clases para mostrar el título de la pista que se está reproduciendo actualmente y permitir que el usuario vuelva a la aplicación.

Esta es la apariencia que debe tener la aplicación cuando complete este tutorial:


Después de esta serie, también exploraremos las funciones relacionadas que puede utilizar para mejorar la aplicación del reproductor de música. Esto incluirá reproducción de video, transmisión de medios, manejo de audio y presentación de datos de medios de diferentes maneras..

1. Crear un controlador

Paso 1

Abre tu principal Actividad Clase y agregue la siguiente declaración de importación:

importar android.widget.MediaController.MediaPlayerControl;

Extienda la línea de apertura de la declaración de clase de la siguiente manera, para que podamos usar el Actividad clase para proporcionar control de reproducción:

La clase pública MainActivity extiende los implementos de actividad MediaPlayerControl 

Pase el cursor sobre el nombre de la clase y seleccione Añadir métodos no implementados. Eclipse agregará varios métodos para el control de reproducción, que adaptaremos a medida que avancemos.

Paso 2

los MediaController la clase presenta un widget estándar con los botones reproducir / pausar, rebobinar, adelantar y saltar (anterior / siguiente). El widget también contiene una barra de búsqueda, que se actualiza a medida que la canción se reproduce y contiene texto que indica la duración de la canción y la posición actual del jugador. Para que podamos configurar los detalles del control, implementaremos una clase para extenderlo. Agrega una nueva clase a tu proyecto, nombrándolo Controlador de musica. En Eclipse, elija android.widget.MediaController como la superclase al crearla.

Dale a la clase el siguiente contenido:

la clase pública MusicController extiende MediaController public MusicController (Context c) super (c);  ocultar público () 

Usted puede adaptar el MediaController clase de varias maneras. Todo lo que queremos hacer es evitar que se oculte automáticamente después de tres segundos anulando la esconder método.

Propina: Es posible que deba modificar el tema que utiliza su aplicación para asegurarse de que el texto del controlador de medios sea claramente visible.

Paso 3

De vuelta en su principal Actividad clase, agregue una nueva variable de instancia:

controlador MusicController privado;

Estaremos configurando el controlador más de una vez en el ciclo de vida de la aplicación, así que hagámoslo con un método auxiliar. Agregue el siguiente fragmento de código a su Actividad clase:

privado void setController () // configura el controlador

Dentro del método, instanciar el controlador:

controlador = nuevo MusicController (este);

Puede configurar varios aspectos de la MediaController ejemplo. Por ejemplo, tendremos que determinar qué sucederá cuando el usuario presione los botones anterior / siguiente. Después de crear una instancia del controlador, establezca estos escuchas de clics:

controller.setPrevNextListeners (new View.OnClickListener () @Override public void onClick (View v) playNext ();, new View.OnClickListener () @Override public void onClick (View v) playPrev (); );

Vamos a implementar jugar siguiente y playPrev un poco más tarde, así que ignora los errores por ahora. Todavía dentro de la setController Método, configure el controlador para que funcione en la reproducción de medios en la aplicación, con su vista de anclaje que se refiere a la lista que incluimos en el diseño:

controller.setMediaPlayer (esto); controller.setAnchorView (findViewById (R.id.song_list)); controller.setEnabled (true);

De nuevo en onCreate, llama al método:

setController ();

También lo llamaremos en otra parte de la clase más adelante..

2. Implementar Control de Reproducción

Paso 1

Recuerda que la reproducción multimedia está ocurriendo en el Servicio clase, pero que la interfaz de usuario proviene de la Actividad clase. En el tutorial anterior, enlazamos el Actividad instancia a la Servicio Por ejemplo, para que podamos controlar la reproducción desde la interfaz de usuario. Los metodos en nuestro Actividad clase que agregamos para implementar el MediaPlayerControl se llamará a la interfaz cuando el usuario intente controlar la reproducción. Necesitaremos el Servicio clase para actuar en este control, así que abre tu Servicio Clase ahora para agregar algunos métodos más a ella:

public int getPosn () return player.getCurrentPosition ();  public int getDur () return player.getDuration ();  public boolean isPng () return player.isPlaying ();  public void pausePlayer () player.pause ();  búsqueda pública de vacíos (int posn) player.seekTo (posn);  public void go () player.start (); 

Todos estos métodos se aplican a las funciones de control de reproducción estándar que el usuario esperará.

Paso 2

Ahora vamos a agregar métodos a la Servicio Clase para saltar a las pistas siguientes y anteriores. Comience con la función anterior:

public void playPrev () songPosn--; si (songPosn<0) songPosn=songs.size()-1; playSong(); 

Disminuimos la variable de índice de la canción, verificamos que no hemos salido del rango de la lista y llamamos al playSong método que hemos añadido. Ahora agregue el método para saltar a la siguiente pista:

// saltar al siguiente void público playNext () songPosn ++; if (songPosn> = songs.size ()) songPosn = 0; playSong (); 

Esto es análogo al método para reproducir la pista anterior en este momento, pero vamos a modificar este método más adelante para implementar la funcionalidad de reproducción aleatoria..

Paso 3

Ahora vuelve a tu Actividad Clase para que podamos hacer uso de estos métodos. Primero agregue los métodos a los que llamamos cuando configuramos el controlador:

// play next private void playNext () musicSrv.playNext (); controller.show (0);  // reproducir el void privado anterior playPrev () musicSrv.playPrev (); controller.show (0); 

Llamamos a los métodos que agregamos al Servicio clase. Vamos a agregar más código a estos más adelante para atender situaciones particulares. Ahora vamos a la MediaPlayerControl métodos de interfaz, que serán llamados por el sistema durante la reproducción y cuando el usuario interactúa con los controles. Estos métodos ya deberían estar en su Actividad clase, así que solo estaremos alterando su implementación.

Comenzar con el hacer pausa método, configurándolo para cierto:

@Override public boolean canPause () return true; 

Ahora haz lo mismo para el canSeekBackward y canSeekForward métodos:

@Override public boolean canSeekBackward () return true;  @Override public boolean canSeekForward () return true; 

Puedes dejar el getAudioSessionId y getBufferPercentage Métodos como son. Enmendar el getCurrentPosition método de la siguiente manera:

@Override public int getCurrentPosition () if (musicSrv! = Null && musicBound && musicSrv.isPng ()) devuelve musicSrv.getPosn (); de lo contrario devuelve 0; 

Las pruebas condicionales son para evitar varias excepciones que pueden ocurrir al usar el Reproductor multimedia y MediaController clases Si intenta mejorar la aplicación de alguna manera, es probable que tenga que dar esos pasos, ya que las clases de reproducción de medios producen muchas excepciones. Note que llamamos al getPosn método de la Servicio clase.

Enmendar el getDuration método similar:

@Override public int getDuration () if (musicSrv! = Null && musicBound && musicSrv.isPng ()) devuelve musicSrv.getDur (); de lo contrario devuelve 0; 

Alterar el está jugando método invocando el isPng método de nuestro Servicio clase:

@Override public boolean isPlaying () if (musicSrv! = Null && musicBound) devuelve musicSrv.isPng (); falso retorno; 

Haz lo mismo para el pausa, tratar de y comienzo métodos:

@Override public void pause () musicSrv.pausePlayer ();  @ Anular pública void seekTo (int pos) musicSrv.seek (pos);  @Override public void start () musicSrv.go (); 

3. Manejar la navegación de nuevo en la aplicación

Paso 1

Recuerda que continuaremos reproduciendo incluso cuando el usuario navegue fuera de la aplicación. Para facilitar esto, mostraremos una notificación que muestra el título de la pista que se está reproduciendo. Al hacer clic en la notificación, el usuario volverá a la aplicación. Cambie de nuevo a su Servicio Clase y agregue las siguientes importaciones adicionales:

import java.util.Random; importar android.app.Notification; importar android.app.PendingIntent;

Ahora muévete a la enPreparado Método, en el que actualmente simplemente iniciamos la reproducción. Después de la llamada a player.start (), añade el siguiente código:

Intención notIntent = new Intent (this, MainActivity.class); notIntent.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendInt = PendingIntent.getActivity (this, 0, notIntent, PendingIntent.FLAG_UPDATE_CURRENT); Notification.Builder builder = nuevo Notification.Builder (este); builder.setContentIntent (pendInt) .setSmallIcon (R.drawable.play) .setTicker (songTitle) .setOngoing (true) .setContentTitle ("Playing") .setContentText (songTitle); Notificación no = builder.build (); startForeground (NOTIFY_ID, no);

Agregaremos las variables que faltan a continuación. los PendingIntent clase llevará al usuario de nuevo a la principal Actividad Clase cuando seleccionan la notificación. Agregue variables para el título de la canción y el ID de notificación en la parte superior de la clase:

private String songTitle = ""; final estático privado int NOTIFY_ID = 1;

Ahora tenemos que poner el título de la canción, en el playSong método, después de la línea en la que recuperamos la canción de la lista (Song playSong = songs.get (songPosn);):

songTitle = playSong.getTitle ();

Desde que hemos llamado setForeground En la notificación, debemos asegurarnos de detenerla cuando el Servicio Se destruye la instancia. Reemplace el siguiente método:

@Override public void onDestroy () stopForeground (true); 

4. Reproducción aleatoria

Paso 1

Recuerda que agregamos un botón de reproducción aleatoria, así que implementemos eso ahora. Primero agregue nuevas variables de instancia al Servicio clase:

barajilla booleana privada = falso; rand aleatorio privado;

Instalar el generador de números aleatorios en onCreate:

rand = new Random ();

Ahora agregue un método para establecer la bandera aleatoria:

public void setShuffle () if (shuffle) shuffle = false; else shuffle = true; 

Simplemente activaremos y desactivaremos la configuración de reproducción aleatoria. Comprobaremos esta bandera cuando el usuario salte a la siguiente pista o cuando una pista termine y la siguiente comience. Enmendar el jugar siguiente método de la siguiente manera:

public void playNext () if (shuffle) int newSong = songPosn; while (newSong == songPosn) newSong = rand.nextInt (songs.size ());  songPosn = newSong;  else songPosn ++; if (songPosn> = songs.size ()) songPosn = 0;  playSong (); 

Si el indicador de reproducción aleatoria está activado, elegimos una nueva canción de la lista al azar, asegurándonos de no repetir la última canción reproducida. Puede mejorar esta funcionalidad utilizando una cola de canciones e impidiendo que se repita cualquier canción hasta que se hayan reproducido todas las canciones..

Paso 2

Ahora podemos dejar que el usuario seleccione la función de reproducción aleatoria. De vuelta en su principal Actividad clase en el onOptionsItemSelected método, modifique la sección de la acción aleatoria para llamar al nuevo método que agregamos al Servicio clase:

caso R.id.action_shuffle: musicSrv.setShuffle (); descanso;

Ahora el usuario podrá usar el elemento del menú para alternar la funcionalidad de reproducción aleatoria.

5. Poner en orden

Paso 1

Ya casi hemos terminado, pero aún necesitamos agregar algunos bits de procesamiento para encargarnos de ciertos cambios, como que el usuario deje la aplicación o haga una pausa en la reproducción. En tus Actividad clase, agregue un par de variables de instancia más:

privado booleano pausado = falso, playbackPaused = falso;

Los usaremos para enfrentar al usuario que regresa a la aplicación después de dejarla e interactuar con los controles cuando la reproducción en sí está en pausa. Anular en pausa para establecer una de estas banderas:

@Override protected void onPause () super.onPause (); pausado = verdadero; 

Ahora anular En resumen:

@Override protected void onResume () super.onResume (); if (paused) setController (); pausado = falso; 

Esto asegurará que el controlador se muestre cuando el usuario vuelva a la aplicación. Anular onStop para esconderlo:

@Override protected void onStop () controller.hide (); super.onStop (); 

Paso 2

Si el usuario interactúa con los controles mientras la reproducción está en pausa, el Reproductor multimedia objeto puede comportarse de forma impredecible. Para hacer frente a esto, vamos a establecer y utilizar el reproducción en pausa bandera. Primero enmendar el jugar siguiente y playPrev métodos:

privado void playNext () musicSrv.playNext (); if (playbackPaused) setController (); playbackPaused = false;  controller.show (0);  private void playPrev () musicSrv.playPrev (); if (playbackPaused) setController (); playbackPaused = false;  controller.show (0); 

Reiniciamos el controlador y actualizamos el reproducción en pausa bandera cuando la reproducción ha sido pausada. Ahora haga cambios similares a los playSong método:

public void songPicked (vista de vista) musicSrv.setSong (Integer.parseInt (view.getTag (). toString ())); musicSrv.playSong (); if (playbackPaused) setController (); playbackPaused = false;  controller.show (0); 

Ahora establece reproducción en pausa a cierto en el pausa método:

@Override public void pause () playbackPaused = true; musicSrv.pausePlayer (); 

Mientras trabajas con el Reproductor multimedia y MediaController En las clases, encontrará que este tipo de procesamiento es un requisito necesario para evitar errores. Por ejemplo, a veces encontrará que la barra de búsqueda del controlador no se actualiza hasta que el usuario interactúa con ella. Estos recursos se comportan de manera diferente en diferentes niveles de API, por lo que es esencial realizar pruebas y ajustes exhaustivos si planea lanzar su aplicación al público. La aplicación que estamos creando en esta serie es realmente solo una base..

Paso 3

Vamos a dar algunos pasos finales para que la aplicación se comporte de manera consistente. Regreso en el Servicio clase, enmendar el en error método:

@Override public boolean onError (MediaPlayer mp, int what, int extra) mp.reset (); falso retorno; 

Simplemente reiniciamos el reproductor, pero es posible que desee mejorar este enfoque.

los en la terminación El método se activará cuando finalice una pista, incluidos los casos en los que el usuario ha elegido una nueva pista o se ha saltado a las pistas siguientes / anteriores, así como cuando la pista llega al final de su reproducción. En este último caso, queremos continuar la reproducción reproduciendo la siguiente pista. Para hacer esto necesitamos verificar el estado de reproducción. Enmiende su en la terminación método:

@Override public void onCompletion (MediaPlayer mp) if (player.getCurrentPosition ()> 0) mp.reset (); playNext (); 

Llamamos al jugar siguiente Método si la pista actual ha llegado a su fin..

Propina: Para asegurarse de que su aplicación no interfiera con otros servicios de audio en el dispositivo del usuario, debe mejorarla para manejar el enfoque de audio con gracia. Hacer el Servicio clase implementar el AudioManager.OnAudioFocusChangeListener interfaz. En el onCreate método, crear una instancia de la AudioManager clase y llamada requestAudioFocus en eso. Finalmente, implementar el onAudioFocusChange Método en su clase para controlar lo que debe suceder cuando la aplicación gana o pierde el enfoque del audio. Vea la sección de Audio Focus en la Guía del desarrollador para más detalles.

Esa es la aplicación básica completa! Sin embargo, es posible que deba realizar mejoras adicionales para que funcione de manera confiable en todos los dispositivos de usuario y niveles de API. Los controles deberían aparecer cada vez que interactúes con la aplicación..


La notificación debería permitirle volver a la aplicación mientras continúa la reproducción..


Conclusión

Ahora hemos completado el reproductor de música básico para Android. Hay muchas maneras de mejorar la aplicación, como agregar soporte para transmisión de medios, video, enfoque de audio y proporcionar diferentes métodos para interactuar con las pistas de música en el dispositivo. Veremos algunas de estas mejoras en futuros tutoriales, destacando cómo puede agregarlas a la aplicación o a otros proyectos de reproducción de medios. Mientras tanto, vea si puede extender la aplicación para crear una funcionalidad adicional o para mejorar la confiabilidad en diferentes dispositivos. Consulte la sección Reproducción de medios de la Guía del desarrollador de Android para obtener más información..