您好!第一次在 stackoverflow 上提问。令人兴奋!哈哈。
我们正在开发一款 Android 游戏,我们会为我们的介绍播放一些背景音乐(我们有一个介绍活动),但我们希望它继续播放到下一个活动,并且也许能够从游戏内的任何位置停止或再次播放音乐应用程序。
我们目前正在做的是在 Intro Activity 中使用 MediaPlayer 播放 bgm。但是,一旦用户离开该 Activity,我们就会停止播放音乐。我们必须使用类似服务之类的东西吗?或者 MediaPlayer/SoundPool 就足够了?如果有人知道答案,我们很乐意与我们分享。谢谢!
您还可以创建一个使用媒体播放器播放音乐的服务,如下所示。
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() {
}
}
使用 SoundPools 或 MediaPlayers 创建静态 SoundManager。
创建一个名为 keepMusicGoing 的静态标志。
创建第一个活动时开始播放音乐。
切换活动时,将 keepMusicGoing 设置为 true。
在活动的 onStop 事件中检查 keepMusicGoing 是否为 true,如果是,则保持音乐打开,然后将 keepMusicGoing 设置为 false。
如果他们按下主页按钮,keepMusicGoing 标志将为 false,因此当活动失去焦点时音乐将停止。
给我发电子邮件,我可以向您发送几个我编写的 SoundManager,其中一个使用 MediaPlayers,另一个使用 SoundPools
乍得
如果我正确理解你的情况,那么我已经遇到过几次同样的问题了。我正在使用不同的线程在我的应用程序中播放音乐。此实现传递了对上下文的静态引用,我知道该上下文在播放音乐时将处于活动状态。
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”标志的方法。我认为只使用 Activity 的 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");
创建本地资源的 Uri。
希望这有帮助。
通过结合 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();
}
}
}
就是这样,超级简单!
创建一个带有一个静态 MediaPlayer 的类 所以每次调用它时实例都是相同的(因为它是静态的)