Servicio integral de música a prueba de fallas de Android en múltiples actividades
Sé que esta pregunta se ha formulado muchas veces antes y puede parecer un conglomerado de varias preguntas, pero creo que es relevante e importante para muchos desarrolladores; Necesito crear una música de fondo.Service
que puede ejecutarse en varias actividades para mi juego de Android que finaliza cuando la aplicación finaliza y se detiene en todas las circunstancias siguientes:
Activity
Que tiene su propia música se inicia. (Reanudar cuando estoActivity
acabados Esto pasa a ser unAndEngine
actividad.)Se presiona la pantalla de inicio y la aplicación queda en segundo plano, o se termina la aplicación. Se reanuda cuando la aplicación vuelve al primer plano. Requiere el uso deonUserLeaveHint()
. Otro enlace útil.El teléfono recibe una llamada e interrumpe la aplicación. Se reanuda cuando la llamada ha sido tratada. Requiere el uso deTelephonyManager
Similar aesta.La pantalla está bloqueada. (Se reanuda después de que la pantalla haya sido desbloqueada). Requiere el uso deACTION_USER_PRESENT
, que pareceser muy problemático.Básicamente, la música se detiene cada vez que no se muestra la aplicación o cuando se muestra al usuario la actividad especial de # 1.Arriba está todo lo que necesito y la información que he reunido.Mi código actual básicamente se pareceesta.
Me parece curioso queAndEngine
se las arregla para no tener ninguno de estos problemas con su música, así que quizás buscar en el código fuente ayudaría a alguien que busca una respuesta. Estoy usandoLa última versión funcional de GLES1 de Google Code..
También he echado un vistazo a los siguientes enlaces para crear una buena música.Service
:
Me gustaria la solucionService
a:
BroadcastReceivers
y adiciones / permisos del manifiesto de Android si es posibleAutocontenido y comprobación de errores.Otras notas
Actualmente, todas las actividades que requieren la música de fondo extienden una clase especial común.La música necesita hacer un bucle pero solo corre una sola pista.Gracias a todos por adelantado! ¡La mejor de las suertes!
Editar - Aquí hay fragmentos de código, siéntase libre de mejorar o ignorar:
Reproductor de medios Wrapper
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.preference.PreferenceManager;
import android.util.Log;
public class CarefulMediaPlayer {
final SharedPreferences sp;
final MediaPlayer mp;
private boolean isPlaying = false;
public CarefulMediaPlayer(final MediaPlayer mp, final MusicService ms) {
sp = PreferenceManager.getDefaultSharedPreferences(ms.getApplicationContext());
this.mp = mp;
}
public void start() {
if (sp.getBoolean("com.embed.candy.music", true) && !isPlaying) {
mp.start();
isPlaying = true;
}
}
public void pause() {
if (isPlaying) {
mp.pause();
isPlaying = false;
}
}
public void stop() {
isPlaying = false;
try {
mp.stop();
mp.release();
} catch (final Exception e) {}
}
}
Servicio de musica
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
public class MusicService extends Service {
static CarefulMediaPlayer mPlayer = null;
@Override
public IBinder onBind(final Intent arg0) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
final MediaPlayer mp = MediaPlayer.create(this, R.raw.title_music);
mp.setLooping(true);
mPlayer = new CarefulMediaPlayer(mp,this);
}
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
mPlayer.start();
return 1;
}
@Override
public void onStart(final Intent intent, final int startId) {
}
public IBinder onUnBind(final Intent arg0) {
return null;
}
public static void onStop() {
mPlayer.stop();
}
public static void onPause() {
if (mPlayer!=null) {
mPlayer.pause();
}
}
public static void onResume() {
if (mPlayer!=null) {
mPlayer.start();
}
}
@Override
public void onDestroy() {
mPlayer.stop();
mPlayer = null;
}
@Override
public void onLowMemory() {
}
}
Clase de actividad base mejorada
import android.app.Activity;
import android.content.Intent;
import android.os.PowerManager;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
public abstract class BetterActivity extends Activity {
private boolean isHome = true;
@Override
protected void onResume() {
System.gc();
super.onResume();
MusicService.onResume();
isHome = true;
}
@Override
protected void onPause() {
if (((TelephonyManager)getSystemService(TELEPHONY_SERVICE)).getCallState()==TelephonyManager.CALL_STATE_RINGING
|| !((PowerManager)getSystemService(POWER_SERVICE)).isScreenOn()) {
MusicService.onPause();
}
super.onPause();
System.gc();
}
@Override
public boolean onKeyDown (final int keyCode, final KeyEvent ke) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
isHome = false;
default:
return super.onKeyDown(keyCode, ke);
}
}
@Override
public void startActivity(final Intent i) {
isHome = false;
super.startActivity(i);
}
@Override
protected void onUserLeaveHint() {
if (isHome) {
MusicService.onPause();
}
super.onUserLeaveHint();
}
}