【问题标题】:Playing BG Music Across Activities in Android在 Android 中跨活动播放 BG 音乐
【发布时间】:2011-01-07 01:29:04
【问题描述】:

你好!第一次在 stackoverflow 上提问。令人兴奋!哈哈。

我们正在开发一款 Android 游戏,并为我们的介绍播放一些背景音乐(我们有一个 Intro Activity),但我们希望它继续播放到下一个 Activity,也许能够停止或再次播放音乐应用程序中的任何位置。

我们目前正在做的是在 Intro Activity 中使用 MediaPlayer 播放 bgm。但是,一旦用户离开该 Activity,我们就会停止播放音乐。我们是否必须为此使用服务之类的东西?还是 MediaPlayer/SoundPool 就足够了?如果有人知道答案,我们将非常感谢您与我们分享。谢谢!

【问题讨论】:

  • 我刚遇到同样的问题,想知道你怎么知道什么时候停止音乐?如果你停止 onDestroy 服务,那么它会在子活动之间停止它 - 你怎么知道最后一个游戏活动何时关闭以停止音乐?

标签: java android media background-music


【解决方案1】:

您还可以创建一个使用媒体播放器播放音乐的服务,如下所示。

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() {

    }
}

【讨论】:

    【解决方案2】:

    使用 SoundPools 或 MediaPlayers 创建一个静态 SoundManager。

    创建一个名为 keepMusicGoing 的静态标志。

    在创建第一个活动时开始播放音乐。

    当切换活动时,将 keepMusicGoing 设置为 true。

    在活动的 onStop 事件中检查 keepMusicGoing 是否为真,如果是则让音乐保持打开状态,然后将 keepMusicGoing 设置为假。

    如果他们按下主页按钮,keepMusicGoing 标志将为 false,因此当活动失去焦点时音乐将停止。

    给我发电子邮件,我可以向您发送我编写的几个 SoundManager,其中一个使用 MediaPlayers,另一个使用 SoundPool

    乍得

    【讨论】:

    • 是的,我们也是这样做的。 vladikoff 将链接发布到我们想到使用静态音乐管理器的地方。
    • 嘿乍得,你能把这些例子发给我吗?我的电子邮件 ID 是 sourabhrustagi1@gmail.com。
    • 我遇到了这种方法的问题。我的应用程序支持旋转,当设备旋转时调用 onStop,当用户按下主页时也会调用它。旋转时我不想停止音乐,但是当按下主页时我会这样做,不知道如何区分事件,有什么想法吗?
    • 完美!有点难以理解,但效果很好!感谢分享!
    【解决方案3】:

    如果我正确理解您的情况,那么我曾多次遇到同样的问题。我正在使用不同的线程在我的应用程序中播放音乐。此实现将静态引用传递给我知道在音乐播放期间将处于活动状态的 Context。

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

    【讨论】:

      【解决方案4】:

      首先,我使用了由乍得提供的保留“keepMusicPlaying”标志的方法。我认为只使用活动的 onStart 和 onStop 方法更优雅。

      创建一个自己的类“SoundManager”并从您的所有活动 onStart 和 onStop 中调用其中的一些 onStart 和 onStop 类(或使用基本活动类)。使用 startCounter(onstart 中的 startCounter++ 和 onstop 中的 startCounter--)跟踪 onStart 和 onStop。因为新活动的开始是在旧活动的 onStop 之前调用的,所以您总是知道 onStart 是第一次调用(startCounter == 1)还是从另一个活动开始(startCounter == 2)。与 onStope 相同(startCounter == 0 表示应用已关闭,startCounter == 1 表示它只是从旧活动停止但有新活动)。

      通过这种方式,您可以将所有内容封装到 SoundManager 中,而不必在应用内的每个活动启动时调用一些 keepMusicPlaying 方法/标志。

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

      【讨论】:

        【解决方案5】:

        您可以尝试使用AsyncPlayer,但您应该保留对该类的引用以停止播放声音。

        您可以使用 Uri uri = Uri.parse("android.resource://com.stackoverlof.android/raw/ beep.mp3"); 为本地资源创建一个 Uri。

        希望这会有所帮助。

        【讨论】:

          【解决方案6】:

          通过结合 Chad 和 Kedu 的答案并添加我自己的风格,我创建了这个可行的解决方案:

          // Parent Activity which every Activity extends
          public class ParentActivity extends AppCompatActivity {
          
              @Override
              protected void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
              }
          
              @Override
              protected void onStart() {
                  super.onStart();
                  Music.onStart();
              }
          
              @Override
              protected void onStop() {
                  super.onStop();
                  Music.onStop();
              }
          }
          
          // Controller class for handling background music
          public abstract class Music {
          
              private static MediaPlayer mediaPlayer;
              private static int startCounter = 0;
          
              public static void onStart() {
                  startCounter++;
                  if (startCounter == 1) {
                      mediaPlayer = MediaPlayer.create(InitializeActivity.getContext(), R.raw.background_music);
                      mediaPlayer.setLooping(true);
                      mediaPlayer.setVolume(1f, 1f);
                      mediaPlayer.start();
                  }
              }
          
              public static void onStop() {
                  startCounter--;
                  if (startCounter == 0) {
                      mediaPlayer.stop();
                      mediaPlayer.release();
                  }
              }
          }
          

          就是这样,超级简单!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多