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..
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 androidO 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..
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..
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.
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.
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..
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á.
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..
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 ();
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);
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..
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.
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 ();
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..
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..
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..
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..