android 竖屏自定义录制视频

来源:互联网 发布:网络电视剧上瘾全集 编辑:程序博客网 时间:2024/05/18 01:19

1.按住录制松开录制完成

2.录制倒计时

3.Seekbar展示

4.录制视频声音大小展示


废话不多说 直接上代码 注释很详细

** * [camera.setDisplayOrientation(90);// 设置预览视频时时竖屏] * * @author ly * @version 1.0 * @date 2016年8月1日 下午4:10:37 **/@SuppressLint("NewApi")public class VideoActivity extends Activity implements Callback,        MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener {    private SurfaceView mSurfaceview;    private Button  mBtnStartPress;// 开始停止录制按键    private MediaRecorder mRecorder;// 录制视频的类    private SurfaceHolder mSurfaceHolder;// 显示视频    private Camera camera;    private int flag = 1;    private View rcChat_popup;//显示出音量大小    private Handler mHandler = new Handler();    private long startVoiceT, endVoiceT;    private static final int POLL_INTERVAL = 300;    private Chronometer timedown;//显示倒计时    private LinearLayout voice_rcd_hint_rcding;    private long timeTotalInS = 0;    private long timeLeftInS = 0;    private ImageView volume;    private ProgressBar mProgressBar;    private int mRecordMaxTime = 10;// 一次拍摄的最长时间    private Handler handler = new Handler() {        public void handleMessage(android.os.Message msg) {            switch (msg.what) {                case 1:// 开始录制//                    timeView.setText(time + "s");                    break;                case 2:// 录制结束                    Toast.makeText(VideoActivity.this, "录制完成", Toast.LENGTH_SHORT).show();                    break;            }        }        ;    };    private CamcorderProfile mProfile;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置全屏        getWindow().setFormat(PixelFormat.TRANSLUCENT); // 选择支持半透明模式,在有surfaceview的activity中使用。        setContentView(R.layout.video_layout);// 加载布局        mSurfaceview = (SurfaceView) findViewById(R.id.surfaceview);        mBtnStartPress = (Button) findViewById(R.id.btn_press);        rcChat_popup = this.findViewById(R.id.rcChat_popup);        timedown = (Chronometer) findViewById(R.id.timedown);        voice_rcd_hint_rcding = (LinearLayout) this.findViewById(R.id.voice_rcd_hint_rcding);        volume = (ImageView) this.findViewById(R.id.volume);        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);        mProgressBar.setMax(mRecordMaxTime);//设置最大值        mBtnStartPress.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View view, MotionEvent event) {                // TODO Auto-generated method stub                if (event.getAction() == MotionEvent.ACTION_DOWN) {                    mBtnStartPress.setBackgroundColor(getResources().getColor(R.color.actionbar_blue));                    mBtnStartPress.setText("松开  结束");                    mBtnStartPress.setTextColor(getResources().getColor(R.color.voice));                    int[] location = new int[2];                    mBtnStartPress.getLocationInWindow(location); // 获取在当前窗口内的绝对坐标                    int btn_rc_Y = location[1];                    int btn_rc_X = location[0];                    if (flag == 1) {                        if (!Environment.getExternalStorageDirectory().exists()) {                            Toast.makeText(VideoActivity.this, "No SDCard", Toast.LENGTH_LONG).show();                            return false;                        }                        System.out.println(event.getY() + "..." + btn_rc_Y + "...." + event.getX() + "...." + btn_rc_X);                        if (event.getY() < btn_rc_Y && event.getX() > btn_rc_X) {//判断手势按下的位置是否是语音录制按钮的范围内                            rcChat_popup.setVisibility(View.VISIBLE);                            mHandler.postDelayed(new Runnable() {                                public void run() {                                }                            }, 300);                            startVoiceT = SystemClock.currentThreadTimeMillis();                            recordMedia();                            down();                            timedown.setVisibility(View.VISIBLE);                            //设置录音时间                            initTimer(mRecordMaxTime);                            timedown.start();                            flag = 2;                        }                    }                } else if (event.getAction() == MotionEvent.ACTION_UP) {                    mBtnStartPress.setBackgroundColor(getResources().getColor(R.color.voice));                    mBtnStartPress.setText("按住  拍摄");                    mBtnStartPress.setTextColor(Color.BLACK);                    timedown.stop();                    if (flag == 2) {                        rcChat_popup.setVisibility(View.GONE);                        timedown.setVisibility(View.GONE);                        up();                        flag = 1;                    } else {                        voice_rcd_hint_rcding.setVisibility(View.GONE);                        up();                        endVoiceT = SystemClock.currentThreadTimeMillis();                        flag = 1;                        int time = (int) ((endVoiceT - startVoiceT) / 1000);                        System.out.println(time);                    }                }                return false;            }        });        SurfaceHolder holder = mSurfaceview.getHolder();// 取得holder        holder.addCallback(this); // holder加入回调接口        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置,要不出错.        mProfile = CamcorderProfile.get(0, 6);    }    public void recordMedia() {        mHandler.postDelayed(mPollTask, POLL_INTERVAL);        // 获取类的实例        recorder = ExtAudioRecorder.getInstanse(true); // false为未压缩的录音(WAV)  true为压缩的        recorder.recordChat(Environment.getExternalStorageDirectory()                .getAbsolutePath()+ File.separator, "upload_media.wav");        //开始录音    }    private Runnable mSleepTask = new Runnable() {        public void run() {            up();        }    };    private ExtAudioRecorder recorder = null;    private Runnable mPollTask = new Runnable() {        public void run() {            double amp = recorder.getAmplitude();//            double amp = mSensor.getAmplitude();            updateDisplay(amp);            mHandler.postDelayed(mPollTask, POLL_INTERVAL);        }    };    private void updateDisplay(double signalEMA) {        switch ((int) signalEMA) {            case 0:            case 1:                volume.setImageResource(R.drawable.amp1);                break;            case 2:            case 3:                volume.setImageResource(R.drawable.amp2);                break;            case 4:            case 5:                volume.setImageResource(R.drawable.amp3);                break;            case 6:            case 7:                volume.setImageResource(R.drawable.amp4);                break;            case 8:            case 9:                volume.setImageResource(R.drawable.amp5);                break;            case 10:            case 11:                volume.setImageResource(R.drawable.amp6);                break;            default:                volume.setImageResource(R.drawable.amp7);                break;        }    }    /**     * 初始化计时器,计时器是通过widget.Chronometer来实现的     *     * @param total 一共多少秒     */    private void initTimer(int total) {        this.timeTotalInS = total;        this.timeLeftInS = total;        timedown.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {            @Override            public void onChronometerTick(Chronometer chronometer) {                if (timeLeftInS <= 0) {                    Toast.makeText(VideoActivity.this, "录像时间到", Toast.LENGTH_SHORT).show();                    timedown.stop();                    //录像停止                    rcChat_popup.setVisibility(View.GONE);                    timedown.setVisibility(View.GONE);                    return;                }                timeLeftInS--;                refreshTimeLeft();                // 设置进度条                mProgressBar.setProgress((int) (mRecordMaxTime - timeLeftInS));            }        });    }    private void refreshTimeLeft() {        this.timedown.setText("录音时间剩余:" + timeLeftInS);        //TODO 格式化字符串    }    public void  down(){        // 开始        if (mRecorder == null) {            mRecorder = new MediaRecorder(); // 创建mediarecorder的对象        }        try {            camera.unlock();            mRecorder.setCamera(camera);            mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);// 这两项需要放在setOutputFormat之前            mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// 设置录制视频源为Camera(相机)            //mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//            // 设置录制完成后视频的封装格式THREE_GPP为3gp.MPEG_4为mp4            //1.8 以上            mRecorder.setProfile(mProfile);//这句是让视频文件在PC端也能视频竖屏播放的保证,跟下面注释了的不能联用            // 这两项需要放在setOutputFormat之后//          mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//          mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);// 设置录制的视频编码h263////          mRecorder.setVideoSize(800, 480);// 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错//          mRecorder.setVideoFrameRate(30);// 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错            mRecorder.setMaxDuration(10000);// 设置最大的录制时间            // mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());            // 设置路径            String path = getSDPath();            if (path != null) {                File dir = new File(path + "/TestCameraFile");                if (!dir.exists()) {                    dir.mkdir();                }                path = dir + "/" + getDate() + ".mp4";                mRecorder.setOutputFile(path);                mRecorder.setOrientationHint(90);                mRecorder.prepare();// 准备录制                mRecorder.start(); // 开始录制                mRecorder.setOnErrorListener(this);                mRecorder.setOnInfoListener(this);            }        } catch (Exception e) {            e.printStackTrace();        }    }    public void up(){        // 停止        mHandler.removeCallbacks(mSleepTask);        mHandler.removeCallbacks(mPollTask);        try {                mRecorder.stop();  //停止                mRecorder.reset(); // 重置                mProgressBar.setProgress(0);                handler.sendEmptyMessageDelayed(2, 1000);            } catch (Exception e) {                e.printStackTrace();            }    }    /**     * 使用时间对录像起名     *     * @return     */    public static String getDate() {        Calendar ca = Calendar.getInstance();        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");        String date = sdf.format(ca.getTimeInMillis());        return date;    }    /**     * 获取SD path     *     * @return     */    public String getSDPath() {        File sdDir = null;        boolean sdCardExist = Environment.getExternalStorageState().equals(                android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在        if (sdCardExist) {            sdDir = Environment.getExternalStorageDirectory();// 获取跟目录            // Toast.makeText(this,sdDir.toString(),Toast.LENGTH_LONG).show();            return sdDir.toString();        } else {            Toast.makeText(this, "没有SD卡", Toast.LENGTH_LONG).show();        }        return null;    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width,                               int height) {        camera = Camera.open(); // 获取Camera实例        try {            camera.setPreviewDisplay(holder);            mSurfaceview.setLayoutParams(new LinearLayout.LayoutParams(width,                    height));        } catch (Exception e) {            // 如果出现异常,则释放Camera对象            camera.release();        }        camera.setDisplayOrientation(90);// 设置预览视频时时竖屏        // 启动预览功能        camera.startPreview();        // 将holder,这个holder为开始在onCreate里面取得的holder,将它赋给mSurfaceHolder        mSurfaceHolder = holder;    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        // 将holder,这个holder为开始在onCreate里面取得的holder,将它赋给mSurfaceHolder        mSurfaceHolder = holder;    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        // TODO Auto-generated method stub        // surfaceDestroyed的时候同时对象设置为null        mSurfaceview = null;        mSurfaceHolder = null;        if (mRecorder != null) {            mRecorder.release(); // Now the object cannot be reused            mRecorder = null;        }        if (camera != null) {            camera.release();            camera = null;        }    }    @Override    public void onInfo(MediaRecorder arg0, int what, int arg2) {        // TODO Auto-generated method stub        if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {        } else if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {        }    }    @Override    public void onError(MediaRecorder arg0, int what, int extra) {        // TODO Auto-generated method stub        if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {        }    }}


布局


<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <SurfaceView        android:id="@+id/surfaceview"        android:layout_width="fill_parent"        android:layout_height="0dp"        android:layout_weight="15" />    <ProgressBar        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="0.3"        style="?android:attr/progressBarStyleHorizontal"        android:max="100"        android:progress="0"        android:id="@+id/progressBar"        android:layout_gravity="center_horizontal" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"        android:background="@color/voice"        android:orientation="horizontal">        <TextView            android:id="@+id/textView1"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_centerHorizontal="true"            android:layout_weight="2"            android:gravity="center"            android:text="0S"            android:visibility="gone" />        <Chronometer            android:id="@+id/timedown"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="30:00"            android:textColor="@color/actionbar_blue"            android:textSize="13sp"            android:visibility="gone" />        <Button            android:id="@+id/stops"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_centerHorizontal="true"            android:layout_weight="9"            android:background="@color/voice"            android:text="点击  录制"            android:textSize="16dp"            android:visibility="gone" />        <Button            android:id="@+id/btn_press"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_centerHorizontal="true"            android:layout_weight="9"            android:background="@color/voice"            android:text="按住  录制"            android:textSize="16dp" />        <LinearLayout            android:id="@+id/rcChat_popup"            android:layout_width="0dp"            android:layout_height="fill_parent"            android:layout_weight="3"            android:gravity="center"            android:orientation="horizontal"            android:visibility="gone">            <LinearLayout                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:gravity="center"                android:orientation="vertical">                <include                    layout="@layout/rcd_hint_window"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_gravity="center" />            </LinearLayout>        </LinearLayout>    </LinearLayout></LinearLayout>

音频的一个类,为了展示出录制视频声音大小

public class ExtAudioRecorder {    private final static int[] sampleRates = {44100, 22050, 11025, 8000, 5512};    private static ExtAudioRecorder result = null;    public static ExtAudioRecorder getInstanse(Boolean recordingCompressed) {        if (recordingCompressed) {            result = new ExtAudioRecorder(false, AudioSource.MIC,                    sampleRates[3], AudioFormat.CHANNEL_CONFIGURATION_MONO,                    AudioFormat.ENCODING_PCM_8BIT);        } else {            int i = 2;//            do {            result = new ExtAudioRecorder(true, AudioSource.MIC,                    sampleRates[i], AudioFormat.CHANNEL_CONFIGURATION_MONO,                    AudioFormat.ENCODING_PCM_16BIT);//            } while ((++i < sampleRates.length)//                    & !(result.getState() == ExtAudioRecorder.State.INITIALIZING));        }        return result;    }    /**     * INITIALIZING : recorder is initializing; READY : recorder has been     * initialized, recorder not yet started RECORDING : recording ERROR :     * reconstruction needed STOPPED: reset needed     */    public enum State {        INITIALIZING, READY, RECORDING, ERROR, STOPPED    }    ;    public static final boolean RECORDING_UNCOMPRESSED = true;    public static final boolean RECORDING_COMPRESSED = false;    // The interval in which the recorded samples are output to the file    // Used only in uncompressed mode    private static final int TIMER_INTERVAL = 120;    // Toggles uncompressed recording on/off; RECORDING_UNCOMPRESSED /    // RECORDING_COMPRESSED    private boolean rUncompressed;    // Recorder used for uncompressed recording    private AudioRecord audioRecorder = null;    // Recorder used for compressed recording    private MediaRecorder mediaRecorder = null;    // Stores current amplitude (only in uncompressed mode)    private int cAmplitude = 0;    // Output file path    private String filePath = null;    // Recorder state; see State    private State state;    // File writer (only in uncompressed mode)    private RandomAccessFile randomAccessWriter;    // Number of channels, sample rate, sample size(size in bits), buffer size,    // audio source, sample size(see AudioFormat)    private short nChannels;    private int sRate;    private short bSamples;    private int bufferSize;    private int aSource;    private int aFormat;    // Number of frames written to file on each output(only in uncompressed    // mode)    private int framePeriod;    // Buffer for output(only in uncompressed mode)    private byte[] buffer;    // Number of bytes written to file after header(only in uncompressed mode)    // after stop() is called, this size is written to the header/data chunk in    // the wave file    private int payloadSize;    /**     * Returns the state of the recorder in a RehearsalAudioRecord.State typed     * object. Useful, as no exceptions are thrown.     *     * @return recorder state     */    public State getState() {        return state;    }    /*     *      * Method used for recording.     */    private AudioRecord.OnRecordPositionUpdateListener updateListener = new AudioRecord.OnRecordPositionUpdateListener() {        public void onPeriodicNotification(AudioRecord recorder) {            audioRecorder.read(buffer, 0, buffer.length); // Fill buffer            try {                randomAccessWriter.write(buffer); // Write buffer to file                payloadSize += buffer.length;                if (bSamples == 16) {                    for (int i = 0; i < buffer.length / 2; i++) { // 16bit                        // sample                        // size                        short curSample = getShort(buffer[i * 2],                                buffer[i * 2 + 1]);                        if (curSample > cAmplitude) { // Check amplitude                            cAmplitude = curSample;                        }                    }                } else { // 8bit sample size                    for (int i = 0; i < buffer.length; i++) {                        if (buffer[i] > cAmplitude) { // Check amplitude                            cAmplitude = buffer[i];                        }                    }                }            } catch (IOException e) {                Log.e(ExtAudioRecorder.class.getName(),                        "Error occured in updateListener, recording is aborted");                // stop();            }        }        public void onMarkerReached(AudioRecord recorder) {            // NOT USED        }    };    /**     * Default constructor     * <p/>     * Instantiates a new recorder, in case of compressed recording the     * parameters can be left as 0. In case of errors, no exception is thrown,     * but the state is set to ERROR     */    public ExtAudioRecorder(boolean uncompressed, int audioSource,                            int sampleRate, int channelConfig, int audioFormat) {        try {            rUncompressed = uncompressed;            if (rUncompressed) { // RECORDING_UNCOMPRESSED                if (audioFormat == AudioFormat.ENCODING_PCM_16BIT) {                    bSamples = 16;                } else {                    bSamples = 8;                }                if (channelConfig == AudioFormat.CHANNEL_CONFIGURATION_MONO) {                    nChannels = 1;                } else {                    nChannels = 2;                }                aSource = audioSource;                sRate = sampleRate;                aFormat = audioFormat;                framePeriod = sampleRate * TIMER_INTERVAL / 1000;                bufferSize = framePeriod * 2 * bSamples * nChannels / 8;                if (bufferSize < AudioRecord.getMinBufferSize(sampleRate,                        channelConfig, audioFormat)) { // Check to make sure                    // buffer size is not                    // smaller than the                    // smallest allowed one                    bufferSize = AudioRecord.getMinBufferSize(sampleRate,                            channelConfig, audioFormat);                    // Set frame period and timer interval accordingly                    framePeriod = bufferSize / (2 * bSamples * nChannels / 8);                    Log.w(ExtAudioRecorder.class.getName(),                            "Increasing buffer size to "                                    + Integer.toString(bufferSize));                }                audioRecorder = new AudioRecord(audioSource, sampleRate,                        channelConfig, audioFormat, bufferSize);                if (audioRecorder.getState() != AudioRecord.STATE_INITIALIZED)                    throw new Exception("AudioRecord initialization failed");                audioRecorder.setRecordPositionUpdateListener(updateListener);                audioRecorder.setPositionNotificationPeriod(framePeriod);            } else { // RECORDING_COMPRESSED                mediaRecorder = new MediaRecorder();                mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);                mediaRecorder                        .setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);                mediaRecorder                        .setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);            }            cAmplitude = 0;            filePath = null;            state = State.INITIALIZING;        } catch (Exception e) {            if (e.getMessage() != null) {                Log.e(ExtAudioRecorder.class.getName(), e.getMessage());            } else {                Log.e(ExtAudioRecorder.class.getName(),                        "Unknown error occured while initializing recording");            }            state = State.ERROR;        }    }    /**     * Sets output file path, call directly after construction/reset.     *     */    public void setOutputFile(String argPath) {        try {            if (state == State.INITIALIZING) {                filePath = argPath;                if (!rUncompressed) {                    mediaRecorder.setOutputFile(filePath);                }            }        } catch (Exception e) {            if (e.getMessage() != null) {                Log.e(ExtAudioRecorder.class.getName(), e.getMessage());            } else {                Log.e(ExtAudioRecorder.class.getName(),                        "Unknown error occured while setting output path");            }            state = State.ERROR;        }    }    /**     * Returns the largest amplitude sampled since the last call to this method.     *     * @return returns the largest amplitude since the last call, or 0 when not     * in recording state.     */    public int getMaxAmplitude() {        if (state == State.RECORDING) {            if (rUncompressed) {                int result = cAmplitude;                cAmplitude = 0;                return result;            } else {                try {                    return mediaRecorder.getMaxAmplitude();                } catch (IllegalStateException e) {                    return 0;                }            }        } else {            return 0;        }    }    /**     * Prepares the recorder for recording, in case the recorder is not in the     * INITIALIZING state and the file path was not set the recorder is set to     * the ERROR state, which makes a reconstruction necessary. In case     * uncompressed recording is toggled, the header of the wave file is     * written. In case of an exception, the state is changed to ERROR     */    public void prepare() {        try {            if (state == State.INITIALIZING) {                if (rUncompressed) {                    if ((audioRecorder.getState() == AudioRecord.STATE_INITIALIZED)                            & (filePath != null)) {                        // write file header                        randomAccessWriter = new RandomAccessFile(filePath,                                "rw");                        randomAccessWriter.setLength(0); // Set file length to                        // 0, to prevent                        // unexpected                        // behavior in case                        // the file already                        // existed                        randomAccessWriter.writeBytes("RIFF");                        randomAccessWriter.writeInt(0); // Final file size not                        // known yet, write 0                        randomAccessWriter.writeBytes("WAVE");                        randomAccessWriter.writeBytes("fmt ");                        randomAccessWriter.writeInt(Integer.reverseBytes(16)); // Sub-chunk                        // size,                        // 16                        // for                        // PCM                        randomAccessWriter.writeShort(Short                                .reverseBytes((short) 1)); // AudioFormat, 1 for                        // PCM                        randomAccessWriter.writeShort(Short                                .reverseBytes(nChannels));// Number of channels,                        // 1 for mono, 2 for                        // stereo                        randomAccessWriter                                .writeInt(Integer.reverseBytes(sRate)); // Sample                        // rate                        randomAccessWriter.writeInt(Integer.reverseBytes(sRate                                * bSamples * nChannels / 8)); // Byte rate,                        // SampleRate*NumberOfChannels*BitsPerSample/8                        randomAccessWriter                                .writeShort(Short                                        .reverseBytes((short) (nChannels                                                * bSamples / 8))); // Block                        // align,                        // NumberOfChannels*BitsPerSample/8                        randomAccessWriter.writeShort(Short                                .reverseBytes(bSamples)); // Bits per sample                        randomAccessWriter.writeBytes("data");                        randomAccessWriter.writeInt(0); // Data chunk size not                        // known yet, write 0                        buffer = new byte[framePeriod * bSamples / 8                                * nChannels];                        state = State.READY;                    } else {                        Log.e(ExtAudioRecorder.class.getName(),                                "prepare() method called on uninitialized recorder");                        state = State.ERROR;                    }                } else {                    mediaRecorder.prepare();                    state = State.READY;                }            } else {                Log.e(ExtAudioRecorder.class.getName(),                        "prepare() method called on illegal state");                release();                state = State.ERROR;            }        } catch (Exception e) {            if (e.getMessage() != null) {                Log.e(ExtAudioRecorder.class.getName(), e.getMessage());            } else {                Log.e(ExtAudioRecorder.class.getName(),                        "Unknown error occured in prepare()");            }            state = State.ERROR;        }    }    /**     * Releases the resources associated with this class, and removes the     * unnecessary files, when necessary     */    public void release() {        if (state == State.RECORDING) {            stop();        } else {            if ((state == State.READY) & (rUncompressed)) {                try {                    randomAccessWriter.close(); // Remove prepared file                } catch (IOException e) {                    Log.e(ExtAudioRecorder.class.getName(),                            "I/O exception occured while closing output file");                }                (new File(filePath)).delete();            }        }        if (rUncompressed) {            if (audioRecorder != null) {                audioRecorder.release();            }        } else {            if (mediaRecorder != null) {                mediaRecorder.release();            }        }    }    /**     * Resets the recorder to the INITIALIZING state, as if it was just created.     * In case the class was in RECORDING state, the recording is stopped. In     * case of exceptions the class is set to the ERROR state.     */    public void reset() {        try {            if (state != State.ERROR) {                release();                filePath = null; // Reset file path                cAmplitude = 0; // Reset amplitude                if (rUncompressed) {                    audioRecorder = new AudioRecord(aSource, sRate,                            nChannels + 1, aFormat, bufferSize);                } else {                    mediaRecorder = new MediaRecorder();                    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);                    mediaRecorder                            .setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);                    mediaRecorder                            .setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);                }                state = State.INITIALIZING;            }        } catch (Exception e) {            Log.e(ExtAudioRecorder.class.getName(), e.getMessage());            state = State.ERROR;        }    }    /**     * Starts the recording, and sets the state to RECORDING. Call after     * prepare().     */    public void start() {        if (state == State.READY) {            if (rUncompressed) {                payloadSize = 0;                audioRecorder.startRecording();                audioRecorder.read(buffer, 0, buffer.length);            } else {                mediaRecorder.start();            }            state = State.RECORDING;        } else {            Log.e(ExtAudioRecorder.class.getName(),                    "start() called on illegal state");            state = State.ERROR;        }    }    /**     * Stops the recording, and sets the state to STOPPED. In case of further     * usage, a reset is needed. Also finalizes the wave file in case of     * uncompressed recording.     */    public void stop() {        if (state == State.RECORDING) {            if (rUncompressed) {                audioRecorder.stop();                try {                    randomAccessWriter.seek(4); // Write size to RIFF header                    randomAccessWriter.writeInt(Integer                            .reverseBytes(32 + payloadSize));                    randomAccessWriter.seek(40); // Write size to Subchunk2Size                    // field                    randomAccessWriter.writeInt(Integer                            .reverseBytes(payloadSize));                    randomAccessWriter.close();                } catch (IOException e) {                    Log.e(ExtAudioRecorder.class.getName(),                            "I/O exception occured while closing output file");                    state = State.ERROR;                }            } else {                try{                    mediaRecorder.stop();                }catch(Exception e){                }finally {                    state = State.STOPPED;                }            }            state = State.STOPPED;        } else {            Log.e(ExtAudioRecorder.class.getName(),                    "stop() called on illegal state");            state = State.ERROR;        }    }    /*     *      * Converts a byte[2] to a short, in LITTLE_ENDIAN format     */    private short getShort(byte argB1, byte argB2) {        return (short) (argB1 | (argB2 << 8));    }    /**     * 录制wav格式文件     *     */    public File recordChat(String savePath, String fileName) {        File dir = new File(savePath);        // 如果该目录没有存在,则新建目录        if (dir.list() == null) {            dir.mkdirs();        }        // 获取录音文件        File file = new File(savePath + fileName);        // 设置输出文件        result.setOutputFile(savePath + fileName);        result.prepare();        // 开始录音        result.start();        return file;    }    /**     * 停止录音     *     *  mediaRecorder 待停止的录音机     * @return 返回     */    public void stopRecord() {        if (result != null) {            result.stop();            result.release();            result = null;        }    }    public double getAmplitude() {        if (result != null)            return (result.getMaxAmplitude() / 2700.0);        else            return 0;    }}

权限  习惯弄很多 省的麻烦


<!-- 授予录音权限 --><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-feature android:name="android.hardware.camera" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-feature android:name="android.hardware.camera.autofocus" /><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.CAMERA" /><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><uses-permission android:name="android.permission.GET_ACCOUNTS" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /><uses-permission android:name="android.permission.NFC" /><uses-permission android:name="android.permission.READ_CONTACTS" /><uses-permission android:name="android.permission.READ_SYNC_SETTINGS" /><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.SET_WALLPAPER" /><uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_READ" /><uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE" /><uses-permission android:name="android.permission.USE_CREDENTIALS" /><uses-permission android:name="android.permission.VIBRATE" /><uses-permission android:name="android.permission.WAKE_LOCK" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_SETTINGS" /><uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />

1 0