如何在我的安卓应用程序中播放res/raw文件夹中的mp3文件?

28

我在安卓应用的res/raw文件夹中有一个小的(200kb)mp3文件。我正在尝试从Eclipse模拟器中运行它。它在R文件中被识别为一个资源,但是当我尝试进行准备/启动时,我的活动会崩溃!是否还有其他地方需要更改,也许是在清单文件中?

MediaPlayer mPlayer = MediaPlayer.create(FakeCallScreen.this, R.raw.mysoundfile);
try { mPlayer.prepare(); mPlayer.start(); } catch (IOException e) { // 稍后处理 }

1
请将logcat输出放在这里,否则我们无法识别错误。 - Konstantin Burov
3个回答

79

在开始活动即onCreate时,放置以下代码。

  public void onCreate(Bundle savedInstanceState) {


        super.onCreate(savedInstanceState);         
        setContentView(R.layout.main);

        MediaPlayer mPlayer = MediaPlayer.create(FakeCallScreen.this, R.raw.mysoundfile);
        mPlayer.start();

    }

在停止活动时,即在onDestroy中放置以下代码。

   public void onDestroy() {

    mPlayer.stop();
    super.onDestroy();

}
希望这可以帮到你 :)

您还可以查看此网站以获取更详细的教程 http://marakana.com/forums/android/examples/59.html - Muhammad Shahab
它成功了!哈哈,显然我不需要mPlayer.prepare(),谢谢 :) - damonkashu

9
您可能更喜欢使用SoundPool类。它在播放声音时可以减少延迟,并提供其他便利功能,例如在需要同时播放太多声音时可以优先处理声音。
根据文档,SoundPool是一组样本,可以从APK内部的资源或文件系统中的文件中加载到内存中。SoundPool库使用MediaPlayer服务将音频解码为原始16位PCM单声道或立体声流。这允许应用程序使用压缩流进行打包,而无需承受在播放期间解压缩的CPU负载和延迟。
例如:
/**
 * How many sounds can be played at once.
 */
private static final int MAX_SOUND_POOL_STREAMS = 4;

/**
 * Modify this as part of your own priority scheme. Higher numbers mean higher
 * priority. If you don't care, it's okay to use the same priority for every
 * sound.
 */
private static final int NORMAL_PRIORITY = 10;

private int mySoundId;

@Override
public void setupContent() {
    this.soundPool = new SoundPool(MAX_SOUND_POOL_STREAMS,
            AudioManager.STREAM_MUSIC, 100);
    this.mySoundId = this.soundPool.load(this.getApplicationContext(),
            R.raw.mySound, 1);
}

@Override
private void playMySound() {
    this.soundPool.play(this.mySoundId, 1, 1, NORMAL_PRIORITY, 0, 1);
}

Sound pool 适用于短时音效(5 秒),而不是长时间的音乐或声音。 - Atif Mukhtiar
@AtifMukhtiar:没错!正是那个问题中提到的200KB MP3的解决方案。 - Michael Scheper
我有一个大小为174KB的.ogg声音文件,时长为14秒。但是这个声音只播放了5秒,它是以44KHz创建的。然后我创建了一个16KHz的声音,我能够播放10秒钟。 - Atif Mukhtiar
很抱歉它对你不起作用。看起来有一个1MB的缓冲限制。我想这将适用于从MP3或OGG解压缩后的声音。https://dev59.com/f2Yr5IYBdhLWcg3wy9SA - Michael Scheper

3

这是我在项目中使用的一个静态方法。我将它添加到我的Utils类中:

    public static void playSound(final Context context, final SoundType type)
    {

            new Thread(new Runnable()
            {

                @Override
                public void run()
                {
                    MediaPlayer mediaPlayer = new MediaPlayer();
                    int resId = -1;
                    switch (type)
                    {
                    case INCOMING_NOTIFICATION:
                        resId=R.raw.noti_sound;
                        break;
                    case SEND_BETTING_SLIP:
                        resId=R.raw.slip_sent;
                        break;
                    case TRIVIA_RIGHT_ANSWER:
                        resId=R.raw.game_bonus;
                        break;
                    case TRIVIA_WRONG_ANSWER:
                        resId=R.raw.whistle_referee_trivia_bad_answer;
                        break;
                    }

                    if (resId != -1)
                    {
                        mediaPlayer = MediaPlayer.create(context, resId);
                        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                        mediaPlayer.setLooping(false);
                        mediaPlayer.start();

                        while (mediaPlayer.isPlaying() == true)
                        {
                        }
                    }
                }
            }).start();

        }
}

现在我定义了一个枚举(SoundType),并将mp3文件放置在res文件夹下的raw文件夹中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接