通常来说,在进行android项目开发的时候可以通过mediarecorder和audiorecord这两个工具来实现录音的功能,mediarecorder直接把麦克风的数据存到文件,并且能够直接进行编码(如amr,mp3等),而audiorecord则是读取麦克风的音频流。本文使用audiorecord读取音频流,使用audiotrack播放音频流,通过“边读边播放”以及增大音量的方式来实现一个简单的助听器程序。
此处需要注意:由于目前的android模拟器还不支持audiorecord,因此本程序需要编译之后放到真机运行。
先贴出本文程序运行截图:
另外还要注意:在本程序音量调节只是程序内部调节音量而已,要调到最大音量还需要手动设置系统音量。
使用audiorecord必须要申请许可,在androidmanifest.xml里面添加这句:
1
|
<uses-permission android:name= "android.permission.record_audio" ></uses-permission> |
main.xml的源码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?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的源码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
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 ); } } }; } |
希望本文所述实例对大家的android项目开发有一定的借鉴价值。