0

我正在制作一个应用程序,只要触摸并按住图像按钮,它就会记录音频。我通过以下代码实现了这一点:

public class MainActivity extends Activity {

MediaRecorder recorder;
MediaPlayer mediaPlayer;

//STORAGE PATHS
String storagePath;
String externalStoragePath;

//FULL OUTPUT PATHS
String externalOutputPath;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //AUDIO RECORDER
    recorder = new MediaRecorder();
    recorder.reset();       
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
    {
        externalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
        externalOutputPath = externalStoragePath + File.separator + "/Android/data/com.whizzappseasyvoicenotepad/test.mp3";
        recorder.setOutputFile(externalOutputPath);
    }
    else
    {
        storagePath = Environment.getDataDirectory().getAbsolutePath();
        recorder.setOutputFile(storagePath + "/Android/data/com.whizzappseasyvoicenotepad/test.mp3");
    }

    //IMAGE BUTTON ONTOUCHLISTENER
    final ImageButton recBtn = (ImageButton) findViewById(R.id.recButton);
    recBtn.setOnTouchListener(new OnTouchListener(){

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            if (event.getAction() == MotionEvent.ACTION_DOWN)
            {
                recBtn.setImageResource(R.drawable.record_btn_pressed);
                try {
                    recorder.prepare();
                    recorder.start();
                } catch (IllegalStateException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            else if (event.getAction() == MotionEvent.ACTION_UP)
            {
                recBtn.setImageResource(R.drawable.record_btn);
                try {
                    recorder.prepare();
                    recorder.stop();
                    recorder.reset();
                    recorder.release();
                    recorder = null;
                } catch (IllegalStateException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Log.i(STORAGE_SERVICE, "File saved to: " + externalStoragePath + "/Android/data/com.whizzappseasyvoicenotepad/test.3gp");
            }
            return true;
        }

    });
} //END OF ONCREATE

现在,在我停止录制后,我在文件管理器(Android 应用程序)中搜索了 mp3 文件并尝试播放它,但它不起作用。它说该文件无法播放。

然后我还尝试在应用程序中添加一个“测试播放”按钮,尝试使用 MediaPlayer 播放录制的文件,但它也不起作用。当我按下播放按钮时,应用程序崩溃了。

public void testPlay (View v) throws IllegalArgumentException, SecurityException, IllegalStateException, IOException{
    mediaPlayer = new MediaPlayer();
    mediaPlayer.setDataSource(externalOutputPath);
    mediaPlayer.start();
}

是的,我确实将 android:onClick="testPlay" 添加到 xml 文件中

日志文件:

07-31 16:51:43.938: E/MediaPlayer(26918): Unable to to create media player
07-31 16:51:43.953: E/AndroidRuntime(26918): FATAL EXCEPTION: main
07-31 16:51:43.953: E/AndroidRuntime(26918): java.lang.IllegalStateException: Could not execute method of the activity
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.view.View$1.onClick(View.java:3633)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.view.View.performClick(View.java:4240)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.view.View$PerformClick.run(View.java:17721)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.os.Handler.handleCallback(Handler.java:730)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.os.Handler.dispatchMessage(Handler.java:92)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.os.Looper.loop(Looper.java:137)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.app.ActivityThread.main(ActivityThread.java:5103)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at java.lang.reflect.Method.invokeNative(Native Method)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at java.lang.reflect.Method.invoke(Method.java:525)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at dalvik.system.NativeStart.main(Native Method)
07-31 16:51:43.953: E/AndroidRuntime(26918): Caused by: java.lang.reflect.InvocationTargetException
07-31 16:51:43.953: E/AndroidRuntime(26918):    at java.lang.reflect.Method.invokeNative(Native Method)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at java.lang.reflect.Method.invoke(Method.java:525)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.view.View$1.onClick(View.java:3628)
07-31 16:51:43.953: E/AndroidRuntime(26918):    ... 11 more
07-31 16:51:43.953: E/AndroidRuntime(26918): Caused by: java.io.IOException: setDataSourceFD failed.: status=0x80000000
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.media.MediaPlayer.setDataSource(Native Method)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.media.MediaPlayer.setDataSource(MediaPlayer.java:981)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.media.MediaPlayer.setDataSource(MediaPlayer.java:960)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at android.media.MediaPlayer.setDataSource(MediaPlayer.java:918)
07-31 16:51:43.953: E/AndroidRuntime(26918):    at com.whizzappseasyvoicenotepad.MainActivity.testPlay(MainActivity.java:99)
07-31 16:51:43.953: E/AndroidRuntime(26918):    ... 14 more

权限:

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
4

4 回答 4

0
java.lang.IllegalStateException

通常表示您的 manifest.xml 中缺少权限

于 2013-07-31T14:58:22.810 回答
0

这是记录 AMR-NB 的代码示例(onClick 方法)

注意:bitRate、sampleRate、FilePath、fileTyp=3gp

如果您准备好播放器以与录制的内容相等,那么您的 IO 错误应该会消失...

        if (isRecording) return;
        tmpFilNme = "me" +Calendar.getInstance().getTime().toString().hashCode();
        view.setKeepScreenOn(true);
        File dir = Environment.getExternalStorageDirectory();          
        File appDir = new File(dir, "PictureComment");
        if (!appDir.exists()) appDir.mkdir();
        recordFilePath = new File(appDir, tmpFilNme +".3gp").getAbsolutePath();
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 

        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mRecorder.setAudioEncodingBitRate(12200);
        mRecorder.setAudioSamplingRate(8000); // this is the MIME rate

        mRecorder.setOutputFile(recordFilePath);
        try {
            mRecorder.prepare();
            mRecorder.start();
            isRecording = true;
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 
于 2013-07-31T18:02:33.290 回答
0

我仍然不确定是什么问题,但我认为我停止录制的方式有问题(整个尝试,捕捉事情)。我只是重写了整个代码并将 MediaRecorder 放在了两种不同的方法中。startRecording() 和 stopRecording() 方法。现在它完美地工作了!

开始录音()

public void startRecording (){
     recorder = new MediaRecorder();
     recorder.reset();      
     recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
     recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
     recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
     if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
     {
         externalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
         externalOutputPath = externalStoragePath + File.separator + "/Android/data/com.whizzappseasyvoicenotepad/test.mp3";
         recorder.setOutputFile(externalOutputPath);
     }
     else
     {
        storagePath = Environment.getDataDirectory().getAbsolutePath();
        recorder.setOutputFile(storagePath + "/Android/data/com.whizzappseasyvoicenotepad/test.mp3");
     }
     recorder.setOnErrorListener(errorListener);
     recorder.setOnInfoListener(infoListener);

     try {
        recorder.prepare();
        recorder.start();
    } catch (IllegalStateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

停止录制()

public void stopRecording() {
    if (null != recorder) {
        recorder.stop();
        recorder.reset();
        recorder.release();

        recorder = null;
    }
}
于 2013-08-01T20:00:40.497 回答
0

我正在使用 AudioRecord 类,并在单独的线程中读取流并在执行过程中写入文件。

我希望通过提供我正在使用的代码,您可以解决您的问题。祝你好运。

In my Constructor:
    bufferSize = AudioRecord.getMinBufferSize(mSampleRate,
            mNbChannels, RECORDER_AUDIO_ENCODING);

private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

public void start() 
{
    System.out.println("SoundRecorder JAVA: start");
    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
            mSampleRate, mNbChannels,
            RECORDER_AUDIO_ENCODING, bufferSize);

    recorder.startRecording();

    isRecording = true;

    recordingThread = new Thread(new Runnable() 
    {

        @Override
        public void run() {
            writeAudioDataToFile();
        }
    }, "AudioRecorder Thread");

    recordingThread.start();
}

private void writeAudioDataToFile() 
{
    byte data[] = new byte[bufferSize];
    String filename = mTempPath;
    FileOutputStream os = null;
    mRecordFile = new File(filename);

    try {
        os = new FileOutputStream(filename);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    int read = 0;

    if (null != os) 
    {
        while (isRecording) 
        {
            read = recorder.read(data, 0, bufferSize);

            Log.i("SoundRecord", "read " + read + " bytes. Wrote In file: " + filename);

            if (AudioRecord.ERROR_INVALID_OPERATION != read) {
                try {
                    os.write(data);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        try {
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

public void stop() 
{
    if (null != recorder) 
    {
        System.out.println("SoundRecorder JAVA: stop");
        isRecording = false;

        recorder.stop();
        recorder.release();

        recorder = null;
        recordingThread = null;
    }
}
于 2013-07-31T17:31:42.317 回答