Android可以通过MediaRecorder和AudioRecord这两个工具来实现录音,MediaRecorder直接把麦克风的数据存到文件,并且能够直接进行编码(如AMR,MP3等),而AudioRecord则是读取麦克风的音频流。本文使用AudioRecord读取音频流,使用AudioTrack播放音频流,通过“边读边播放”以及增大音量的方式来实现一个简单的助听器程序。

PS:由于目前的Android模拟器还不支持AudioRecord,因此本程序需要编译之后放到真机运行。

先贴出本文程序运行截图:

PS:程序音量调节只是程序内部调节音量而已,要调到最大音量还需要手动设置系统音量。

使用AudioRecord必须要申请许可,在AndroidManifest.xml里面添加这句:

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

main.xml的源码如下:

<?xml version="1.0" encoding="utf-8"?>    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"        android:orientation="vertical" android:layout_width="fill_parent"        android:layout_height="fill_parent">            <Button android:layout_height="wrap_content" android:id="@+id/btnRecord"            android:layout_width="fill_parent" android:text="开始边录边放"></Button>        <Button android:layout_height="wrap_content"            android:layout_width="fill_parent" android:text="停止" android:id="@+id/btnStop"></Button>        <Button android:layout_height="wrap_content" android:id="@+id/btnExit"            android:layout_width="fill_parent" android:text="退出"></Button>        <TextView android:id="@+id/TextView01" android:layout_height="wrap_content"            android:text="程序音量调节" android:layout_width="fill_parent"></TextView>        <SeekBar android:layout_height="wrap_content" android:id="@+id/skbVolume"            android:layout_width="fill_parent"></SeekBar>        </LinearLayout>   

testRecord.java的源码如下:

package com.testRecord;        import android.app.Activity;    import android.media.AudioFormat;    import android.media.AudioManager;    import android.media.AudioRecord;    import android.media.AudioTrack;    import android.media.MediaRecorder;    import android.os.Bundle;    import android.view.View;    import android.widget.Button;    import android.widget.SeekBar;    import android.widget.Toast;        public class testRecord extends Activity {        /** Called when the activity is first created. */        Button btnRecord, btnStop, btnExit;        SeekBar skbVolume;//调节音量        boolean isRecording = false;//是否录放的标记        static final int frequency = 44100;        static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;        static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;        int recBufSize,playBufSize;        AudioRecord audioRecord;        AudioTrack audioTrack;            @Override        public void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            setContentView(R.layout.main);            setTitle("助听器");            recBufSize = AudioRecord.getMinBufferSize(frequency,                    channelConfiguration, audioEncoding);                playBufSize=AudioTrack.getMinBufferSize(frequency,                    channelConfiguration, audioEncoding);            // -----------------------------------------            audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency,                    channelConfiguration, audioEncoding, recBufSize);                audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,                    channelConfiguration, audioEncoding,                    playBufSize, AudioTrack.MODE_STREAM);            //------------------------------------------            btnRecord = (Button) this.findViewById(R.id.btnRecord);            btnRecord.setOnClickListener(new ClickEvent());            btnStop = (Button) this.findViewById(R.id.btnStop);            btnStop.setOnClickListener(new ClickEvent());            btnExit = (Button) this.findViewById(R.id.btnExit);            btnExit.setOnClickListener(new ClickEvent());            skbVolume=(SeekBar)this.findViewById(R.id.skbVolume);            skbVolume.setMax(100);//音量调节的极限            skbVolume.setProgress(70);//设置seekbar的位置值            audioTrack.setStereoVolume(0.7f, 0.7f);//设置当前音量大小            skbVolume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {                                @Override                public void onStopTrackingTouch(SeekBar seekBar) {                    float vol=(float)(seekBar.getProgress())/(float)(seekBar.getMax());                    audioTrack.setStereoVolume(vol, vol);//设置音量                }                                @Override                public void onStartTrackingTouch(SeekBar seekBar) {                    // TODO Auto-generated method stub                }                                @Override                public void onProgressChanged(SeekBar seekBar, int progress,                        boolean fromUser) {                    // TODO Auto-generated method stub                }            });        }            @Override        protected void onDestroy() {            super.onDestroy();            android.os.Process.killProcess(android.os.Process.myPid());        }            class ClickEvent implements View.OnClickListener {                @Override            public void onClick(View v) {                if (v == btnRecord) {                    isRecording = true;                    new RecordPlayThread().start();// 开一条线程边录边放                } else if (v == btnStop) {                    isRecording = false;                } else if (v == btnExit) {                    isRecording = false;                    testRecord.this.finish();                }            }        }            class RecordPlayThread extends Thread {            public void run() {                try {                    byte[] buffer = new byte[recBufSize];                    audioRecord.startRecording();//开始录制                    audioTrack.play();//开始播放                                        while (isRecording) {                        //从MIC保存数据到缓冲区                        int bufferReadResult = audioRecord.read(buffer, 0,                                recBufSize);                            byte[] tmpBuf = new byte[bufferReadResult];                        System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult);                        //写入数据即播放                        audioTrack.write(tmpBuf, 0, tmpBuf.length);                    }                    audioTrack.stop();                    audioRecord.stop();                } catch (Throwable t) {                    Toast.makeText(testRecord.this, t.getMessage(), 1000);                }            }        };    }  

更多相关文章

  1. android 程序中运行main方法
  2. ContentProvider详解
  3. android学习笔记16:带提示的输入框
  4. Android核心分析之二十一Android应用框架之AndroidApplication
  5. android 应用程序Activity之间数据传递与共享的几种途径
  6. Android(安卓)WebView的加载超时处理
  7. AndroidManifest.xml文件剖析
  8. 安卓开发到底是什么
  9. 译:Android的一些基础问题(一)

随机推荐

  1. Android与服务器通信
  2. android获取存储卡使用情况
  3. 毕设---android按钮事件
  4. android 使用百度地图画轨迹
  5. android ImageSwitcher案例
  6. Android Fragment 简洁版 list
  7. android seekbar的用法
  8. Android(安卓)之 API级别
  9. android生成缩略图
  10. android每隔5s显示时间