Android:为什么我在点击一下按钮点击后无法播放声音?

时间:2012-03-27 10:50:46

标签: android audio android-ndk media-player

如果用户点击按钮然后播放声音,我就会这样做。但是现在我点击后无法发出水声。我不知道为什么?

以下是我用来播放声音的代码。

代码:

case R.id.lockView:
        playSound(R.raw.dooropen);
        break;
    }

public void playSound(int resources){
    boolean mStartPlaying = true;
    if (mStartPlaying==true){
        mPlayer = new MediaPlayer();
        Uri uri = Uri.parse("android.resource://com.project.iMystick/" + resources);
        try{
            mPlayer.setDataSource(getApplicationContext(),uri);
            mPlayer.prepare();
            mPlayer.start();
        } 
        catch (IOException e){
            Log.e(LOG_TAG, "prepare() failed");
        }
    } 
    else{
       //   stopPlaying();
        //rePlay.setText("Replay");
        mPlayer.release();
        mPlayer = null;
    }
    mStartPlaying = !mStartPlaying;
}

点击一下后,我在logcat中收到了这种错误信息:

日志:

03-27 16:15:02.737: ERROR/MediaPlayer(1057): Error (-19,0)
03-27 16:15:03.858: DEBUG/AudioSink(34): bufferCount (4) is too small and increased to 12
03-27 16:15:03.858: ERROR/AudioFlinger(34): not enough memory for AudioTrack size=32832
03-27 16:15:03.858: DEBUG/MemoryDealer(34):   AudioTrack (0x12abf8, size=1048576)
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     0: 0012ac10 | 0x00000000 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     1: 0012aca0 | 0x00008040 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     2: 0012b5a8 | 0x00010080 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     3: 0012bec8 | 0x000180C0 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     4: 0012c7f0 | 0x00020100 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     5: 0012d1f0 | 0x00028140 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     6: 0012db20 | 0x00030180 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     7: 00136448 | 0x000381C0 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     8: 0013ee00 | 0x00040200 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     9: 0000de10 | 0x00048240 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    10: 0012b708 | 0x00050280 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    11: 00022c70 | 0x000582C0 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    12: 000234c0 | 0x00060300 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    13: 00115e38 | 0x00068340 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    14: 00117a80 | 0x00070380 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    15: 00118798 | 0x000783C0 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    16: 00042228 | 0x00080400 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    17: 0004bd48 | 0x00088440 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    18: 00055998 | 0x00090480 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    19: 0005f5f0 | 0x000984C0 | 0x00003040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    20: 000712b0 | 0x0009B500 | 0x00008040 | A
03-27 16:15:03.867: ERROR/AudioTrack(34): AudioFlinger could not create track, status: -12
03-27 16:15:03.867: ERROR/AudioSink(34): Unable to create audio track
03-27 16:15:03.877: ERROR/MediaPlayer(1057): error (-19, 0)

enter code here

4 个答案:

答案 0 :(得分:6)

您需要释放()媒体播放器,否则资源不会被释放,您很快就会内存不足(因为下次再分配它们)。 所以,我认为你可以玩两次甚至三次......但没有多次没有释放资源

建议一旦不再使用MediaPlayer对象,立即调用release(),以便立即释放与MediaPlayer对象关联的内部播放器引擎使用的资源。资源可能包括单一资源(如硬件加速组件)和调用release()失败可能导致MediaPlayer对象的后续实例回退到软件实现或完全失败。See this link

答案 1 :(得分:2)

MediaPlayer不是按照您尝试使用它的方式运行的。这就是你遇到问题的原因。

播放小音效时,MediaPlayer 不是一个好的选择,因为用户可以很快点击多个按钮,你必须为所有这些按钮创建一个MP对象。只要您单击按钮,就会同步发生。转到 SoundPool 类,它允许您将较小的声音保存在内存中,您可以随时播放它们,而不会出现媒体播放器中的任何延迟。 http://developer.android.com/reference/android/media/SoundPool.html这是一个很好的教程:http://www.anddev.org/using_soundpool_instead_of_mediaplayer-t3115.html

答案 2 :(得分:1)

我认为问题是你没有等到第一个完成(或停止)开始第二个.. 尝试在完成时听取前一个,然后启动下一个..你可以使用setOnCompletionListener。

类似的问题: android playing two songs problem

代码:

    package ooo.iii;

    import java.io.IOException;


    import android.app.Activity;
    import android.media.MediaPlayer;
    import android.net.Uri;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;

    public class Test_audioActivity extends Activity { 
        /** Called when the activity is first created. */
        Button btn;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    //        setContentView(R.layout.main); 
            setContentView(R.layout.main);
            btn=(Button)findViewById(R.id.ss);

            btn.setOnClickListener(new OnClickListener() { 

                @Override
                public void onClick(View v) {
                    playSound(R.raw.musi);

                }
            });

        }



    public void playSound(int resources){
        try{
        boolean mStartPlaying = true;
        MediaPlayer  mPlayer=null;
    if (mStartPlaying==true){

          mPlayer = new MediaPlayer();
        Uri uri = Uri.parse("android.resource://ooo.iii/" + resources);

            mPlayer.setDataSource(getApplicationContext(),uri);
            mPlayer.prepare();
            mPlayer.start();

    } 
    else{
       //   stopPlaying();
        //rePlay.setText("Replay");
        mPlayer.release();
        mPlayer = null;
    }
    mStartPlaying = !mStartPlaying;


    } 
    catch (IOException e){
        Log.e("ERR", "prepare() failed");
    }
    }



}

您需要更改:

1- source @ res / raw / musi ..给你的

res / layout / main.xml中按钮的2-id从ss到你的..

3- Uri uri = Uri.parse(“android.resource://ooo.iii/”+ resources);修改包名称到您的

那就是所有..我在真实设备上进行了测试并点击了很多次并获得了之前仍在播放的新声音

答案 3 :(得分:1)

我遇到了同样的问题,我通过在OnCompletionListener中使用release()方法解决了这个问题:

MediaPlayer mp = MediaPlayer.create(getApplicationContext(), resource);
        mp.start();
        mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                mp.release();
            }
        });