只要按住按钮,我怎样才能在android中录制声音?

时间:2012-06-20 08:57:31

标签: android voice-recording

我想录制语音,只要按住录音按钮并将该语音保存到我项目的原始文件夹中即可。我使用下面的代码。尽管没有出现错误,我无法获得任何输出。可能是什么问题?你有什么建议吗?谢谢,

public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub


    Runnable mAction = new Runnable() {
        public void run() {
            System.out.println("Performing action...");

            int frequency=11025;
            int channelConfiguration=AudioFormat.CHANNEL_CONFIGURATION_MONO;
            int audioEncoding= AudioFormat.ENCODING_PCM_16BIT;
            File file=new File(Environment.getExternalStorageDirectory(),"raw.pcm");

            try{
                file.createNewFile();
            }catch(IOException e){}

            try{
                OutputStream os=new FileOutputStream(file);
                BufferedOutputStream bos=new BufferedOutputStream(os);
                DataOutputStream dos=new DataOutputStream(bos);

                int bufferSize=AudioRecord.getMinBufferSize(frequency, channelConfiguration,
                        audioEncoding);

                short[] buffer=new short[bufferSize];
                audioRecorder=new AudioRecord(MediaRecorder.AudioSource.MIC,
                        frequency, channelConfiguration, audioEncoding, bufferSize);

                audioRecorder.startRecording();

                isRecording=true;

                while(isRecording){

                    int                                    bufferReadResult=audioRecorder.read(buffer, 0,bufferSize);

                    for(int i=0;i<bufferReadResult;i++){

                        dos.writeShort(buffer[i]);

                    }

                }

                audioRecorder.stop();
                dos.close();

            }catch(Throwable t){}

        }
    };

    switch(event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        if (myHandler != null) return true;
        myHandler = new Handler();
        myHandler.postDelayed(mAction, 500);
        break;
    case MotionEvent.ACTION_UP:

        if (myHandler == null) return true;


        isRecording=false;

        myHandler.removeCallbacks(mAction);
        myHandler = null;
        break;
    }

    return false;
}

4 个答案:

答案 0 :(得分:29)

这是你的回答......

import java.io.File;
import java.io.IOException;
import android.app.Activity;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;

public class AudioOnTouchActivity extends Activity {
    Button b1;
    private static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp";
    private static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp4";
    private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
    private MediaRecorder recorder = null;
    private int currentFormat = 0;
    private int output_formats[] = { MediaRecorder.OutputFormat.MPEG_4,             MediaRecorder.OutputFormat.THREE_GPP };
    private String file_exts[] = { AUDIO_RECORDER_FILE_EXT_MP4, AUDIO_RECORDER_FILE_EXT_3GP }; 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        b1=(Button)findViewById(R.id.button1);
        b1.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                switch(event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    AppLog.logString("Start Recording");
                    startRecording();
                    return true;
                case MotionEvent.ACTION_UP:
                    AppLog.logString("stop Recording");
                    stopRecording();
                    break;
                }
                return false;
            }
        });
    }

    private String getFilename(){
        String filepath = Environment.getExternalStorageDirectory().getPath();
        File file = new File(filepath,AUDIO_RECORDER_FOLDER);

        if(!file.exists()){
            file.mkdirs();
        }

        return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + file_exts[currentFormat]);
    }

    private void startRecording(){
        recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(output_formats[currentFormat]);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        recorder.setOutputFile(getFilename());
        recorder.setOnErrorListener(errorListener);
        recorder.setOnInfoListener(infoListener);

        try {
            recorder.prepare();
            recorder.start();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
           @Override
            public void onError(MediaRecorder mr, int what, int extra) {
                AppLog.logString("Error: " + what + ", " + extra);
        }
    };

    private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
        @Override
        public void onInfo(MediaRecorder mr, int what, int extra) {
                AppLog.logString("Warning: " + what + ", " + extra);
        }
    };

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

            recorder = null;
        }
    }
}

AppLog.java文件是

import android.util.Log;

public class AppLog {
private static final String APP_TAG = "AudioRecorder";

public static int logString(String message){
     return Log.i(APP_TAG,message);
}

xml是

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" 
    >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" 
        android:layout_gravity="center"
        android:layout_marginTop="10dp"/>

</LinearLayout>

将这些权限添加到您的清单文件

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
        <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>

答案 1 :(得分:1)

save that voice into the raw folder in my project.

在运行时,您无法在Raw文件夹中保存内容。

您有2个选项可以将其保存在外部存储(如果有)或getFileDir中,即在 / data / data / package目录。

答案 2 :(得分:1)

您可以从这个代码中获取帮助

<强> AudioRecorderActivity.java

public class AudioRecorderActivity extends Activity {
    private static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp";
    private static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp4";
    private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
    private MediaRecorder recorder = null;
    private int currentFormat = 0;
    private int output_formats[] = {
        MediaRecorder.OutputFormat.MPEG_4, MediaRecorder.OutputFormat.THREE_GPP
    };
    private String file_exts[] = {
        AUDIO_RECORDER_FILE_EXT_MP4, AUDIO_RECORDER_FILE_EXT_3GP
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setButtonHandlers();
        enableButtons(false);
        setFormatButtonCaption();
    }

    private void setButtonHandlers() {
        ((Button) findViewById(R.id.btnStart)).setOnClickListener(btnClick);
        ((Button) findViewById(R.id.btnStop)).setOnClickListener(btnClick);
        ((Button) findViewById(R.id.btnFormat)).setOnClickListener(btnClick);
    }

    private void enableButton(int id, boolean isEnable) {
        ((Button) findViewById(id)).setEnabled(isEnable);
    }

    private void enableButtons(boolean isRecording) {
        enableButton(R.id.btnStart, !isRecording);
        enableButton(R.id.btnFormat, !isRecording);
        enableButton(R.id.btnStop, isRecording);
    }

    private void setFormatButtonCaption() {
        ((Button) findViewById(R.id.btnFormat)).setText(getString(R.string.audio_format) + " (" + file_exts[currentFormat] + ")");
    }

    private String getFilename() {
        String filepath = Environment.getExternalStorageDirectory().getPath();
        File file = new File(filepath, AUDIO_RECORDER_FOLDER);

        if (!file.exists()) {
            file.mkdirs();
        }

        return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + file_exts[currentFormat]);
    }

    private void startRecording() {
        recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(output_formats[currentFormat]);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        recorder.setOutputFile(getFilename());
        recorder.setOnErrorListener(errorListener);
        recorder.setOnInfoListener(infoListener);

        try {
            recorder.prepare();
            recorder.start();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

            recorder = null;
        }
    }

    private void displayFormatDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        String formats[] = {
            "MPEG 4", "3GPP"
        };

        builder.setTitle(getString(R.string.choose_format_title)).setSingleChoiceItems(formats, currentFormat, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                currentFormat = which;
                setFormatButtonCaption();

                dialog.dismiss();
            }
        }).show();
    }

    private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {@Override
        public void onError(MediaRecorder mr, int what, int extra) {
            AppLog.logString("Error: " + what + ", " + extra);
        }
    };

    private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {@Override
        public void onInfo(MediaRecorder mr, int what, int extra) {
            AppLog.logString("Warning: " + what + ", " + extra);
        }
    };

    private View.OnClickListener btnClick = new View.OnClickListener() {@Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btnStart:
                {
                    AppLog.logString("Start Recording");

                    enableButtons(true);
                    startRecording();

                    break;
                }
            case R.id.btnStop:
                {
                    AppLog.logString("Start Recording");

                    enableButtons(false);
                    stopRecording();

                    break;
                }
            case R.id.btnFormat:
                {
                    displayFormatDialog();

                    break;
                }
            }
        }
    };
}  

AppLog.java

import android.util.Log;

public class AppLog {
    private static final String APP_TAG = "AudioRecorder";

    public static int logString(String message) {
        return Log.i(APP_TAG, message);
    }
}    

<强> main.xml中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:padding="20dip" >

    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scaleType="fitCenter" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        <Button
            android:id="@+id/btnStart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:text="@string/start_recording" />
        <Button
            android:id="@+id/btnStop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:text="@string/stop_recording" />
        <Button
            android:id="@+id/btnFormat"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:text="Format (mp4)" />
    </LinearLayout>

</LinearLayout>  

答案 3 :(得分:1)

您可以使用我创建的库RecordView

它易于设置,并且模拟与WhatsApp相同的行为。

只需添加观看次数RecordViewRecordButton

即可
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.devlomi.recordview.MainActivity">

<com.devlomi.record_view.RecordView
    android:id="@+id/record_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_toLeftOf="@id/record_button"
    app:slide_to_cancel_arrow="@drawable/ic_keyboard_arrow_left"
    app:slide_to_cancel_text="Slide To Cancel"
    app:slide_to_cancel_margin_right="10dp"/>

<com.devlomi.record_view.RecordButton
    android:id="@+id/record_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    android:background="@drawable/bg_mic"
    android:scaleType="centerInside"
    app:src="@drawable/ic_mic_white"
    />

然后在你的活动中

    RecordView recordView = (RecordView) findViewById(R.id.record_view);
    RecordButton recordButton = (RecordButton) 
     findViewById(R.id.record_button);

    //IMPORTANT
    recordButton.setRecordView(recordView);

最后你可以处理记录状态

    开始录制时
  • onStart
  • 滑动取消时
  • onCancel
  • 完成记录时
  • onFinish ,并以毫秒为单位返回记录的时间
  • 记录时间<= 1秒

  • onLessThanSecond

    recordView.setOnRecordListener(this);
    
    
        @Override
        public void onStart() {
            //Start Recording..
            Log.d("RecordView", "onStart");
        }
    
        @Override
        public void onCancel() {
            //On Swipe To Cancel
            Log.d("RecordView", "onCancel");
    
        }
    
        @Override
        public void onFinish(long recordTime) {
            //Stop Recording..
            String time = getHumanTimeText(recordTime);
            Log.d("RecordView", "onFinish");
    
            Log.d("RecordTime", time);
        }
    
        @Override
        public void onLessThanSecond() {
            //When the record time is less than One Second
            Log.d("RecordView", "onLessThanSecond");
        }