通常来说,在进行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项目开发有一定的借鉴价值。