我知道这个问题之前已经被问过很多次,并且可能看起来是几个问题的集合,但我觉得它对许多开发人员来说是相关和重要的;我需要Service为我的 Android 游戏创建一个可以跨多个活动运行的背景音乐,该音乐在应用程序终止时结束并在以下所有情况下暂停:
- 一个
Activity有自己的音乐的人开始了。(Activity完成后继续。这恰好是一个AndEngine活动。) - 按下主屏幕并且应用程序在后台运行,或者应用程序被终止。当应用程序返回前台时恢复。需要使用
onUserLeaveHint(). 另一个有用的链接。 - 手机接听电话并中断应用程序。呼叫处理完毕后恢复。需要使用
TelephonyManager类似this。 - 屏幕被锁定。(解锁屏幕后恢复。) 需要使用,这
ACTION_USER_PRESENT似乎很 成问题。 - 基本上,只要未显示应用程序或向用户显示来自#1 的特殊活动,音乐就会暂停。
 
以上是我需要的所有内容以及我拼凑的信息。我当前的代码基本上类似于this。
我觉得很好奇AndEngine他们的音乐没有这些问题,所以也许查看源代码会帮助人们寻找答案。我正在使用来自 Google Code 的最后一个功能 GLES1 版本。
我还查看了以下链接以创建好音乐Service:
- 停止后台服务音乐
 - http://www.codeproject.com/Articles/258176/Adding-Background-Music-to-Android-App
 - 安卓背景音乐服务
 - 在 Android 中跨活动播放 BG 音乐
 - http://www.rbgrn.net/content/307-light-racer-20-days-61-64-completion
 
我希望解决方案Service:
- 如果可能,尽量减少使用
BroadcastReceiversAndroid Manifest 添加/权限 - 自包含和错误检查
 
其他注意事项
- 目前所有需要背景音乐的活动都扩展了一个通用的特殊类。
 - 音乐需要循环播放,但只运行一首曲目。
 
提前感谢大家!祝你好运!
编辑 - 以下是代码片段,请随时改进或忽略:
媒体播放器包装
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) {}
    }
}
音乐服务
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() {
    }
}
改进的基础活动类
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();
    }
}