Umfassender ausfallsicherer Musikdienst für Android für mehrere Aktivitäten
Ich weiß, dass diese Frage schon oft gestellt wurde und ein Konglomerat mehrerer Fragen zu sein scheint, aber ich bin der Meinung, dass sie für viele Entwickler relevant und wichtig ist. Ich muss eine Hintergrundmusik erstellenService
Dies kann mehrere Aktivitäten für mein Android-Spiel betreffen, die beendet werden, wenn die Anwendung beendet wird, und unter den folgenden Umständen angehalten werden:
Activity
das hat seine eigene musik gestartet. (Setzen Sie fort, wenn dies geschiehtActivity
endet. Das ist zufällig einAndEngine
Aktivität.)Der Startbildschirm wird gedrückt und die App wird im Hintergrund angezeigt oder die Anwendung wird beendet. Wird fortgesetzt, wenn die App in den Vordergrund zurückkehrt. Benötigt die Verwendung vononUserLeaveHint()
. Ein weiterer hilfreicher Link.Das Telefon empfängt einen Anruf und unterbricht die App. Wird fortgesetzt, wenn der Anruf bearbeitet wurde. Benötigt die Verwendung vonTelephonyManager
ähnlich zudiese.Der Bildschirm ist gesperrt. (Wird fortgesetzt, nachdem der Bildschirm entsperrt wurde.) Erfordert die Verwendung vonACTION_USER_PRESENT
, was zu sein scheintSein sehr problematisch.Grundsätzlich wird die Musik immer dann unterbrochen, wenn die App nicht angezeigt wird oder wenn dem Benutzer die spezielle Aktivität von Nummer 1 angezeigt wird.Oben ist alles, was ich brauche und die Informationen, die ich zusammengestellt habe.Mein aktueller Code ähnelt im Grundediese.
Das finde ich merkwürdigAndEngine
schafft es, keine dieser Probleme mit ihrer Musik zu haben, also könnte ein Blick in den Quellcode jemandem helfen, nach einer Antwort zu suchen. Ich benutzedie letzte funktionsfähige GLES1-Version von Google Code.
Ich habe mir auch die folgenden Links angeschaut, um eine gute Musik zu machenService
:
Ich hätte gerne die LösungService
zu:
BroadcastReceivers
und Android Manifest Ergänzungen / Berechtigungen, wenn möglichSelbstständig und FehlerprüfungWeitere Hinweise
Gegenwärtig bilden alle Aktivitäten, die Hintergrundmusik erfordern, eine gemeinsame Sonderklasse.Die Musik muss geloopt werden, läuft aber nur auf einer Spur.Vielen Dank an alle im Voraus! Viel Glück!
Bearbeiten - Hier sind Codeausschnitte, die Sie gerne verbessern oder ignorieren können:
Media Player 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) {}
}
}
Musikdienst
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() {
}
}
Verbesserte Basisaktivitätsklasse
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();
}
}