【发布时间】:2012-07-14 11:16:51
【问题描述】:
我知道这个问题之前已经被问过很多次,并且可能看起来是几个问题的集合,但我觉得它对许多开发人员来说是相关且重要的;我需要为我的 Android 游戏创建一个可以跨多个活动运行的背景音乐Service,该音乐在应用程序终止时结束并在以下所有情况下暂停:
- 某个有自己音乐的
Activity启动。 (当这个Activity完成时恢复。这恰好是一个AndEngine活动。) - 按下主屏幕,应用程序进入后台,或应用程序终止。当应用程序返回前台时恢复。需要使用
onUserLeaveHint()。 Another helpful link. - 手机接听电话并中断应用程序。呼叫处理完毕后恢复。需要使用类似于this 的
TelephonyManager。 - 屏幕被锁定。 (屏幕解锁后恢复。)需要使用
ACTION_USER_PRESENT,这似乎是be very problematic。 - 基本上,当应用程序未显示或#1 的特殊活动显示给用户时,音乐就会暂停。
以上是我需要的所有内容以及我拼凑的信息。 我当前的代码基本上类似于this。
我觉得很奇怪AndEngine 设法在他们的音乐中没有这些问题,所以也许查看源代码会帮助寻找答案的人。我正在使用the last functional GLES1 version from Google Code。
我还查看了以下链接以及创建好音乐Service:
- Stopping Background Service Music
- http://www.codeproject.com/Articles/258176/Adding-Background-Music-to-Android-App
- Android background music service
- Playing BG Music Across Activities in Android
- http://www.rbgrn.net/content/307-light-racer-20-days-61-64-completion
我希望解决方案Service 到:
- 尽可能减少使用
BroadcastReceivers和 Android Manifest 添加/权限 - 自包含和错误检查
其他说明
- 目前所有需要背景音乐的活动都扩展了一个通用的特殊类。
- 音乐需要循环播放,但只运行一首曲目。
提前感谢大家!祝你好运!
编辑 - 这里是代码 sn-ps,请随意改进或忽略:
媒体播放器包装
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();
}
}
【问题讨论】:
-
我正在尝试自己完成所有目标,并看到了您的问题。任何进展?完成后,我会尽量让你知道这是怎么回事。
-
@ajacian81 有一段时间没有上网站了,我们决定推迟音乐并提前发布测试版。
-
好吧,我会告诉你我的尝试进展如何,我应该在一个月左右得到一些答案。
-
太好了,我等着!
标签: android service background andengine playback