2010-01-19 3 views
30

Hello! Первый раз задать вопрос здесь в stackoverflow. Захватывающе! Ха-ха.Воспроизведение музыки BG на всех мероприятиях в Android

Мы разрабатываем Android-игру, и мы играем фоновую музыку для нашего вступления (у нас есть Intro Activity), но мы хотим, чтобы она продолжала играть на следующем мероприятии и, возможно, была в состоянии остановить или воспроизвести музыку снова из любой точки приложения.

Что мы делаем в данный момент, играем в bgm с помощью MediaPlayer в нашей Intro Activity. Однако мы останавливаем музыку, как только пользователь покидает эту активность. Нужно ли для этого использовать что-то вроде Сервисов? Или достаточно MediaPlayer/SoundPool? Если кто-нибудь знает ответ, мы с радостью оценим, как вы делитесь им с нами. Благодаря!

+1

Я только что столкнулся с той же проблемой и задавался вопросом, как вы знаете, когда остановить музыку? Если вы остановите службу onDestroy, то это остановит ее между subactivities - откуда вы знаете, когда последняя игровая активность закрыта, чтобы остановить музыку? – Tom

ответ

13

По моему опыту использования Сервисов для этого не очень хорошая идея.

фоновой музыки без использования Услуги:

http://www.rbgrn.net/content/307-light-racer-20-days-61-64-completion

+1

Прошло некоторое время с тех пор, как я опубликовал этот вопрос. Я должен был обновить его, когда мы нашли решение. Лучше всего это использовать использование статического музыкального менеджера, а не сервиса. На самом деле ссылка, которую вы опубликовали, является именно той, с которой мы ее основывали. Бог благословит Роберта Грина. – jhie

+0

Почему услуги здесь не очень хорошие? – codeulike

+6

Возможно, я пропустил это, когда пропустил код, но похоже, что он управляет музыкальным менеджером в потоке пользовательского интерфейса. Это не очень хороший дизайн. Музыка и другие (потенциально) интенсивные операции не должны выполняться в потоке пользовательского интерфейса, чтобы избежать закрытия ANR. Это описано в одном из первых первых руководств для разработчиков Android: http://developer.android.com/guide/components/processes-and-threads.html#Threads. См. Другие ответы, касающиеся адресации для правильных примеров. – CatShoes

2

Если я правильно понимаю вашу ситуацию правильно, то я столкнулся с той же проблемой несколько раз. Я использую другой поток для воспроизведения музыки в своих приложениях. Эта реализация передает статическую ссылку на Контекст, который, как я знаю, будет живым на время воспроизведения музыки.

public class AudioPlayer extends Thread { 
private Context c; 
private Thread blinker; 
private File file; 

public AudioPlayer (Context c, File file) { 
    this.c = c; 
    this.file = file; 
} 

public void go() { 
    blinker = this; 
    if(!blinker.isAlive()) { 
     blinker.start(); 
    } 
} 

public void end() { 
    Thread waiter = blinker; 
    blinker = null; 
    if (waiter != null) 
     waiter.interrupt(); 
} 

public void run() { 
    MediaPlayer ap = MediaPlayer.create(c, Uri.fromFile(file)); 
    int duration = ap.getDuration(); 
    long startTime = System.currentTimeMillis(); 
    ap.start(); 
    try { 
     Thread thisThread = Thread.currentThread(); 
     while (this.blinker == thisThread && System.currentTimeMillis() - startTime < duration) {   
      Thread.sleep (500); // interval between checks (in ms) 
     } 
     ap.stop(); 
     ap.release(); 
     ap = null; 
    } catch (InterruptedException e) { 
     Log.d("AUDIO-PLAYER", "INTERRUPTED EXCEPTION"); 
     ap.stop(); 
     ap.release(); 
     ap = null; 
    } 
    } 
} 
1

Вы можете попробовать использовать AsyncPlayer но вы должны сохранить ссылку на класс, чтобы остановить звук от игры.

Вы можете создать Uri для локального ресурса, используя Uri uri = Uri.parse("android.resource://com.stackoverlof.android/raw/ beep.mp3");.

Надеюсь, это поможет.

9

Вы также можете создать сервис, который воспроизводит музыку, используя медиаплеер, как показано ниже.

Intent svc=new Intent(this, BackgroundSoundService.class); 
startService(svc); //OR stopService(svc); 

public class BackgroundSoundService extends Service { 
    private static final String TAG = null; 
    MediaPlayer player; 
    public IBinder onBind(Intent arg0) { 

     return null; 
    } 
    @Override 
    public void onCreate() { 
     super.onCreate(); 


     player = MediaPlayer.create(this, R.raw.idil); 
     player.setLooping(true); // Set looping 
     player.setVolume(100,100); 

    } 
    public int onStartCommand(Intent intent, int flags, int startId) { 


     player.start(); 

     return 1; 
    } 

    public void onStart(Intent intent, int startId) { 
     // TODO 



    } 
    public IBinder onUnBind(Intent arg0) { 
     // TODO Auto-generated method stub 

     return null; 
    } 

    public void onStop() { 

    } 
    public void onPause() { 

    } 
    @Override 
    public void onDestroy() { 

     player.stop(); 
     player.release(); 
    } 

    @Override 
    public void onLowMemory() { 

    } 
} 
4

Создание статического Soundmanager используя либо SoundPools или медиаплееры.

Создайте статический флаг под названием keepMusicGoing.

Начало музыки при создании первой активности.

При переключении активных установок keepMusicGoing на true.

В случае события onStop вашей деятельности проверьте, поддерживает ли keepMusicGoing, если это так, оставив музыку, а затем установите keepMusicGoing на false.

Если они нажимают кнопку дома, флаг keepMusicGoing будет ложным, поэтому музыка остановится, когда действие потеряет фокус.

Напишите мне, и я могу послать вам пару SoundManagers, что я написал один использует медиаплееры и другие SoundPools

Чад

+1

Да, это было так, как мы это сделали. vladikoff разместил ссылку на то, где мы получили идею использования статического менеджера для музыки. – jhie

+0

эй чад вы можете прислать мне эти примеры. Мой адрес электронной почты - [email protected] – Sourabh

+0

Я столкнулся с проблемой такого подхода. Мое приложение поддерживает вращения и когда устройство повернуто onStop, вызывается, и его также вызывают, когда пользователь нажимает на дом. Когда я вращаюсь, я не хочу останавливать музыку, но когда дома нажимают, я не знаю, как различать события, любые идеи? – marchinram

0

Сначала я использовал метод, где держать флаг «keepMusicPlaying» предоставленный Чаде.Я считаю, что его более элегантно просто использовать методы onStart и onStop для вашей деятельности.

Создайте собственный класс SoundManager и вызовите в нем классы onStart и onStop из всех ваших действий onStart и onStop (или используйте базовый класс активности). Следите за onStart и onStop с помощью startCounter (startCounter ++ в onstart и startCounter - в onstop). Поскольку начало нового действия вызывается перед onStop старой активности, вы всегда знаете, вызывается ли onStart в первый раз (startCounter == 1) или запускается из другой вашей активности (startCounter == 2). То же самое с onStope (startCounter == 0 означает, что приложение было закрыто, startCounter == 1 означает его просто остановку от старой активности, но есть новое).

Таким образом вы инкапсулируете все в свой SoundManager вместо того, чтобы называть любой метод keepMusicPlaying/flag при каждом запуске деятельности внутри вашего приложения.

public void OnStart() 
    { 
     startCounter++; 
     if (startCounter == 1) 
     { 
      //start music here 
     } 

    public void OnStop() 
    { 
     startCounter--; 
     if (startCounter == 0) 
     { 
      // stop music here 
     } 
    } 
0

Мой library был разработан, чтобы сделать фон воспроизведения медиа как можно более простым. Попробуйте взглянуть на источник или просто используйте библиотеку, если хотите.