在 Android 中跨活动播放 BG 音乐
你好!第一次在 stackoverflow 上提问。令人兴奋!哈哈。
我们正在开发一个 Android 游戏,我们为我们的介绍播放一些背景音乐(我们有一个介绍活动),但我们希望它继续播放到下一个活动,并且也许能够停止或播放从应用程序内的任何位置再次播放音乐。
我们目前正在做的是在 Intro Activity 中使用 MediaPlayer 播放 bgm。但是,一旦用户离开该 Activity,我们就会停止播放音乐。我们必须使用类似服务之类的东西吗?或者 MediaPlayer/SoundPool 就足够了?如果有人知道答案,我们很乐意与我们分享。谢谢!
Hello! First time to ask a question here at stackoverflow. Exciting! Haha.
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.
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(7)
使用 SoundPools 或 MediaPlayers 创建静态 SoundManager。
创建一个名为 keepMusicGoing 的静态标志。
创建第一个活动时开始播放音乐。
切换活动时,将 keepMusicGoing 设置为 true。
在活动的 onStop 事件中检查 keepMusicGoing 是否为 true,如果是,则保持音乐打开,然后将 keepMusicGoing 设置为 false。
如果他们按下主页按钮,则 keepMusicGoing 标志将为 false,因此当活动失去焦点时音乐将停止。
给我发电子邮件,我可以向您发送我编写的几个 SoundManager,其中一个使用 MediaPlayers,另一个使用 SoundPools
Chad
如果我正确理解你的情况,那么我已经遇到过几次同样的问题了。我正在使用不同的线程在我的应用程序中播放音乐。此实现传递了对上下文的静态引用,我知道该上下文在播放音乐时将处于活动状态。
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;
}
}
}
首先,我使用了 Chad 提供的保留“keepMusicPlaying”标志的方法。我认为仅使用活动的 onStart 和 onStop 方法更优雅。
创建一个自己的类“SoundManager”,并从所有活动 onStart 和 onStop 中调用其中的一些 onStart 和 onStop 类(或使用基活动类)。使用 startCounter 跟踪 onStart 和 onStop(startCounter++ in onstart 和 startCounter-- in 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
}
}
您可以尝试使用 AsyncPlayer 但您应该保留对类以停止播放声音。
您可以使用 Uri uri = Uri.parse("android.resource://com.stackoverlof.android/raw/
。
beep.mp3");
希望这会有所帮助。
通过结合 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();
}
}
}
就是这样,超级简单!
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您还可以创建一个使用媒体播放器播放音乐的服务,如下所示。
You can also create a service which play music using mediaplayer as below.