Комплексный отказоустойчивый музыкальный сервис Android для нескольких видов деятельности
Я знаю, что этот вопрос задавался много раз и может показаться совокупностью нескольких вопросов, но я чувствую, что он актуален и важен для многих разработчиков; Мне нужно создать фоновую музыкуService
которая может выполнять несколько действий для моей игры для Android, которая заканчивается, когда приложение завершается, и приостанавливается при всех следующих обстоятельствах:
Activity
that has its own music is started. (Resume when this Activity
finishes. This happens to be an AndEngine
activity.)
The home screen is pressed and the app is backgrounded, or the application is terminated. Resumes when the app returns to the foreground. Requires use of onUserLeaveHint()
. Another helpful link.
The phone receives a call and interrupts the app. Resumes when the call has been dealt with. Requires use of TelephonyManager
similar to this.
The screen is locked. (Resumes after screen has been unlocked.) Requires use of ACTION_USER_PRESENT
, which seems to be very problematic.
Basically the music pauses whenever the app is not being shown or when the special activity from #1 is being shown to the user.
Выше все, что мне нужно, и информация, которую я собрал воедино.My current code basically resembles этот.
Мне кажется любопытным, чтоAndEngine
не удается решить ни одну из этих проблем со своей музыкой, поэтому, возможно, поиск в исходном коде поможет кому-то найти ответ. Я используюпоследняя функциональная версия GLES1 от Google Code.
Я посмотрел также следующие ссылки на создание хорошей музыкиService
:
Я хотел бы решениеService
чтобы:
BroadcastReceivers
and Android Manifest additions/permissions if possible
Self contained and error checking
Другие заметки
Currently all the activities that require the background music all extend a common special class. The music needs to loop but only runs a single track.Спасибо всем заранее! Удачи!
Редактировать - вот фрагменты кода, которые можно улучшать или игнорировать:
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) {}
}
}
Music Service
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() {
}
}
Improved Base Activity Class
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();
}
}