Java 在 Android 中跨活动播放 BG 音乐

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2097909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 03:31:13  来源:igfitidea点击:

Playing BG Music Across Activities in Android

javaandroidmediabackground-music

提问by jhie

Hello! First time to ask a question here at stackoverflow. Exciting! Haha.

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

We're developing an Android game and we play some background music for our intro (we have an Intro Activity) but we want it to continue playing to the next Activity, and perhaps be able to stop or play the music again from anywhere within the application.

我们正在开发一个 Android 游戏,我们为我们的介绍播放一些背景音乐(我们有一个介绍活动),但我们希望它继续播放到下一个活动,也许能够从任何地方停止或再次播放音乐应用。

What we're doing at the moment is play the bgm using MediaPlayer at our Intro Activity. However, we stop the music as soon as the user leaves that Activity. Do we have to use something like Services for this? Or is MediaPlayer/SoundPool enough? If anyone knows the answer, we'd gladly appreciate your sharing it with us. Thanks!

我们目前正在做的是在我们的介绍活动中使用 MediaPlayer 播放背景音乐。但是,一旦用户离开该 Activity,我们就会停止播放音乐。我们是否必须为此使用服务之类的东西?或者 MediaPlayer/SoundPool 足够了吗?如果有人知道答案,我们很高兴您与我们分享。谢谢!

回答by Shade

If I understand your situation correctly, then I have confronted the same problem a few times. I am using a different thread to play music in my applications. This implementation passes a static reference to a Context that I know will be alive for the time that the music will be playing.

如果我正确理解您的情况,那么我遇到过几次同样的问题。我正在使用不同的线程在我的应用程序中播放音乐。这个实现传递了一个对 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;
    }
    }
}

回答by Jonas Van der Aa

You can try using the AsyncPlayerbut you should keep a reference to the class in order to stop the sound from playing.

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

You can create a Uri to a local resource using Uri uri = Uri.parse("android.resource://com.stackoverlof.android/raw/ beep.mp3");.

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

Hope this helps.

希望这可以帮助。

回答by Maneesh

You can also create a service which play music using mediaplayer as below.

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

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

    }
}

回答by Chad

Create a static SoundManager using either SoundPools or MediaPlayers.

使用 SoundPools 或 MediaPlayers 创建静态 SoundManager。

Create a static flag called keepMusicGoing.

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

Start the music when the first activty is created.

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

When switching actvities set keepMusicGoing to true.

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

On the onStop event of your activities check if keepMusicGoing is true,if so leave the music on, then set keepMusicGoing to false.

在您的活动的 onStop 事件中检查 keepMusicGoing 是否为 true,如果是,请打开音乐,然后将 keepMusicGoing 设置为 false。

If they press the home button the keepMusicGoing flag will be false so the music will stop when the activity loses focus.

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

Email me and I can send you a couple SoundManagers that I wrote one uses MediaPlayers and the other SoundPools

给我发电子邮件,我可以给你发送几个我写的 SoundManagers,一个使用 MediaPlayers,另一个使用 SoundPools

Chad

乍得

回答by Kedu

First i used the method where to keep a "keepMusicPlaying" flag provided by Chad. I think its more elegant to just use the onStart and onStop methods of your activitys.

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

Create an own class "SoundManager" and call some onStart and onStop classes in it from all your activitys onStart and onStop (or use a base activity class). Keep track of the onStart and onStop with a startCounter(startCounter++ in onstart and startCounter-- in onstop). Because the start of a new activity is called before the onStop of the old activity you always know if the onStart is called for the first Time (startCounter == 1) or started from another of your activitys (startCounter == 2). Same with the onStope(startCounter == 0 means the App was closed, startCounter == 1 means its just the stop from an old activity but there is a new).

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

This way you encapsulate everything into your SoundManager instead of having to call some keepMusicPlaying method/flag on every activity start inside your app.

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

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

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

回答by Crossoni

By combining Chad's and Kedu's answers and adding my own flavor, I created this working solution:

通过结合 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();
        }
    }
}

And that's it, super simple!

就是这样,超级简单!