Serviço abrangente de música à prova de falhas do Android em várias atividades
Eu sei que essa pergunta já foi feita muitas vezes e pode parecer um conglomerado de várias questões, mas eu sinto que ela é relevante e importante para muitos desenvolvedores; Eu preciso criar uma música de fundoService
que pode ser executado em várias atividades do meu jogo Android que termina quando o aplicativo é encerrado e pausa em todas as circunstâncias a seguir:
Activity
que tem sua própria música é iniciada. (Retomar quando issoActivity
acabamentos. Isso acontece de ser umAndEngine
atividade.)A tela inicial é pressionada e o aplicativo é em segundo plano ou o aplicativo é encerrado. Continua quando o aplicativo retorna ao primeiro plano. Requer o uso deonUserLeaveHint()
. Outro link útil.O telefone recebe uma chamada e interrompe o aplicativo. Retoma quando a chamada foi tratada. Requer o uso deTelephonyManager
igual aisto.A tela está bloqueada. (Retoma após a tela ter sido desbloqueada.) Requer o uso deACTION_USER_PRESENT
, o que pareceestar muito problemático.Basicamente a música faz uma pausa sempre que o aplicativo não está sendo mostrado ou quando a atividade especial do # 1 está sendo mostrada ao usuário.Acima está tudo o que eu preciso e as informações que eu juntei.Meu código atual basicamente se assemelhaisto.
Eu acho curiosoAndEngine
não consegue ter nenhum desses problemas com suas músicas, então, talvez, procurar no código-fonte ajudaria alguém que estivesse procurando uma resposta. estou a usara última versão funcional GLES1 do Google Code.
Eu dei uma olhada nos links a seguir, bem como na criação de uma boa músicaService
:
Eu gostaria da soluçãoService
para:
BroadcastReceivers
e adições / permissões do manifesto do Android, se possívelAuto-contido e verificação de errosOutras notas
Atualmente todas as atividades que requerem a música de fundo estendem uma classe especial comum.A música precisa de loop, mas só executa uma única faixa.Obrigado a todos antes do tempo! Boa sorte!
Editar - Aqui estão os trechos de código, sinta-se livre para melhorar ou ignorar:
Wrapper do Media Player
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) {}
}
}
Serviço de Música
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() {
}
}
Classe de atividade base aprimorada
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();
}
}