Я знаю, что этот вопрос задавался много раз раньше и может показаться конгломератом нескольких вопросов, но я считаю, что это важно и важно для многих разработчиков; Мне нужно создать фоновую музыку Service
, которая может работать с несколькими действиями для моей игры Android, которая заканчивается, когда приложение завершается и приостанавливается во всех следующих обстоятельствах:
- Запускается определенная
Activity
, которая имеет свою собственную музыку. (Возобновление, когда заканчиваетсяActivity
. Это происходит какAndEngine
.) - Нажимается домашний экран, а приложение зашифровывается, или приложение завершается. Возвращает, когда приложение возвращается на передний план. Требуется использование
onUserLeaveHint()
. Еще одна полезная ссылка. - Телефон получает вызов и прерывает приложение. Возобновляется, когда вызов был обработан. Требуется использовать
TelephonyManager
, аналогичный этому. - Экран заблокирован. (Возобновляется после того, как экран был разблокирован.) Требуется использовать
ACTION_USER_PRESENT
, который, как представляется, be проблематично. - В основном музыка приостанавливается всякий раз, когда приложение не отображается или когда пользователю показан специальный вид активности #.
Выше все, что мне нужно, и информация, которую я собрал вместе. Мой текущий код в основном напоминает этот.
Мне любопытно, что AndEngine
не имеет ни одной из этих проблем с их музыкой, поэтому, возможно, поиск в исходном коде поможет кому-то найти ответ. Я использую последнюю функциональную версию GLES1 из Google Code.
Я также рассмотрел следующие ссылки на создание хорошей музыки Service
:
- Остановка фоновой музыки
- http://www.codeproject.com/Articles/258176/Adding-Background-Music-to-Android-App
- Служба фоновой музыки Android
- Воспроизведение музыки BG через действия в Android
- http://www.rbgrn.net/content/307-light-racer-20-days-61-64-completion
Я хотел бы, чтобы решение Service
:
- Сведите к минимуму использование
BroadcastReceivers
и дополнений/разрешений Android 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();
}
}