Комплексный отказоустойчивый музыкальный сервис Android для различных действий

Я знаю, что этот вопрос задавался много раз раньше и может показаться конгломератом нескольких вопросов, но я чувствую, что он актуален и важен для многих разработчиков; Мне нужно создать фоновую музыку Service, которая может воспроизводиться в нескольких действиях для моей игры для Android, которая заканчивается, когда приложение завершается, и приостанавливается во всех следующих обстоятельствах:

  1. Запускается некий Activityсо своей музыкой. (Возобновить после Activityзавершения. Это оказывается AndEngineактивностью.)
  2. Нажат главный экран, и приложение работает в фоновом режиме или приложение закрывается. Возобновляется, когда приложение возвращается на передний план. Требуется использованиеonUserLeaveHint(). Еще одна полезная ссылка.
  3. Телефон принимает вызов и прерывает работу приложения. Возобновляется после обработки вызова. Требуется использование TelephonyManagerаналогично this .
  4. Экран заблокирован. (Возобновляется после разблокировки экрана. )Требуется использованиеACTION_USER_PRESENT, который кажется равнымоченьпроблемный .
  5. В основном музыка приостанавливается всякий раз, когда приложение не отображается или когда пользователю показывается специальная активность из #1.

Выше все, что мне нужно, и информация, которую я собрал воедино.Мой текущий код в основном напоминает этот .

Мне кажется любопытным, что у AndEngineнет ни одной из этих проблем с музыкой, поэтому, возможно, просмотр исходного кода поможет кому-то найти ответ. Я использую последнюю функциональную версию GLES1 из Google Code .

Я также просмотрел следующие ссылки по созданию хорошей музыкиService:

Я хотел бы получить решение от Serviceдо:

  • По возможности сведите к минимуму использование BroadcastReceiversи дополнений/разрешений манифеста Android
  • . Самодостаточность и проверка ошибок

Другие примечания

  • В настоящее время все действия, требующие фоновой музыки, относятся к общему специальному классу.
  • Музыка должна зацикливаться, но воспроизводит только один трек.

Всем заранее спасибо! Удачи!

Изменить -Вот фрагменты кода, не стесняйтесь их улучшать или игнорировать:

Оболочка медиаплеера

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();
    }

}

25
задан Matthieu Brucher 31 December 2018 в 13:21
поделиться