Android AudioRecord.stop()导致崩溃

时间:2014-01-26 15:59:05

标签: java android audio audio-recording audiorecord

我正在尝试使用AudioRecord(http://developer.android.com/reference/android/media/AudioRecord.html#stop%28%29)在Android上录制音频。我面向Android AudioRecord example

我的代码如下:

import java.io.IOException;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.os.Environment;
import android.view.ViewGroup;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;
import android.content.Context;
import android.util.Log;
import android.media.MediaRecorder;
import android.media.MediaPlayer;
import de.benediktbock.fft.fft;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder.AudioSource;
import java.io.IOException;


public class MainActivity extends Activity {
    private static final String LOG_TAG = "FFTTEST";
    private PlayButton   mPlayButton = null;
    private TextView    realTeil = null;
    private TextView    imgTeil = null;
    private fft         mFFT = null; 

    private int channel_config = AudioFormat.CHANNEL_IN_MONO;
    private int format = AudioFormat.ENCODING_PCM_16BIT;
    private int sampleRate = 8000;
    private int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channel_config, format);
    private AudioRecord audioInput = null; //new AudioRecord(AudioSource.MIC, sampleSize, channel_config, format, bufferSize);
    private short[] audioBuffer = new short[bufferSize];

    private Thread readingThread = null;
    private boolean isRecording = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LinearLayout ll = new LinearLayout(this);
        mPlayButton = new PlayButton(this);

        ll.addView(mPlayButton,new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT,
                0));

        realTeil = new TextView(this);
        ll.addView(realTeil,new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT,
                0));

        imgTeil = new TextView(this);
        ll.addView(imgTeil,new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT,
                0));
        setContentView(ll);

        realTeil.setText("Realteil");
        imgTeil.setText("Imaginärteil");

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    class PlayButton extends Button {
        boolean mStartPlaying = true;

        OnClickListener clicker = new OnClickListener() {
            public void onClick(View v) {
                onPlay(mStartPlaying);
                if (mStartPlaying) {
                    setText("Stop");
                } else {
                    setText("Start");
                }
                mStartPlaying = !mStartPlaying;
            }
        };

        public PlayButton(Context ctx) {
            super(ctx);
            setText("Start");
            setOnClickListener(clicker);
        }
    }

    private void onPlay(boolean start) {
        if (start) {
            startRecording();
        } else {
            stopRecording();
        }

    }

    private void startRecording()
    {
        //create and start recorder
        audioInput = new AudioRecord(AudioSource.MIC, sampleRate, channel_config, format, bufferSize);
        audioInput.startRecording();
        isRecording = true;

        //start reading thread
        readingThread = new Thread(new Runnable() 
            {
                @Override
                public void run() 
                {
                    readAudioToBuffer();
                }
            },"readAudio Thread");
        readingThread.start();
    }

    private void readAudioToBuffer()
    {
        while(isRecording)
        {
            audioInput.read(audioBuffer, 0,bufferSize);
        }
        audioInput.stop(); // on this point the app crashes (after clicking "stop")
        audioInput.release();
        audioInput = null;
    }

    private void stopRecording()
    {
        isRecording = false;
        readingThread = null;
    }
}

我可以毫无问题地开始录音。但当我停止记录时,应用程序崩溃了。我发现它在audioInput.stop()行崩溃了。

sombody知道问题出在哪里吗?我完全不知道。

1 个答案:

答案 0 :(得分:0)

private void stopRecording()
{
    isRecording = false;
   // readingThread = null;
}

设置isRecording = false后,您将分配readingThread = null,但线程无法完成其任务。所以它会引导你的应用程序出现。