Android提供了两个API用于实现录音功能:android.media.AudioRecord、android.media.MediaRecorder。java
网上有不少谈论这两个类的资料。如今大体总结下:android
一、AudioRecordgit
主要是实现边录边播(AudioRecord+AudioTrack)以及对音频的实时处理(如会说话的汤姆猫、语音)github
优势:语音的实时处理,能够用代码实现各类音频的封装数组
缺点:输出是PCM语音数据,若是保存成音频文件,是不可以被播放器播放的,因此必须先写代码实现数据编码以及压缩app
示例:ide
使用AudioRecord类录音,并实现WAV格式封装。录音20s,输出的音频文件大概为3.5M左右(已写测试代码)post
二、MediaRecorder测试
已经集成了录音、编码、压缩等,支持少许的录音音频格式,大概有.aac(API = 16) .amr .3gpui
优势:大部分以及集成,直接调用相关接口便可,代码量小
缺点:没法实时处理音频;输出的音频格式不是不少,例如没有输出mp3格式文件
示例:
使用MediaRecorder类录音,输出amr格式文件。录音20s,输出的音频文件大概为33K(已写测试代码)
三、音频格式比较
WAV格式:录音质量高,可是压缩率小,文件大
AAC格式:相对于mp3,AAC格式的音质更佳,文件更小;有损压缩;通常苹果或者Android SDK4.1.2(API 16)及以上版本支持播放
AMR格式:压缩比比较大,但相对其余的压缩格式质量比较差,多用于人声,通话录音
至于经常使用的mp3格式,使用MediaRecorder没有该视频格式输出。一些人的作法是使用AudioRecord录音,而后编码成wav格式,再转换成mp3格式
再贴上一些测试工程。
功能描述:
一、点击“录音WAV文件”,开始录音。录音完成后,生成文件/sdcard/FinalAudio.wav
二、点击“录音AMR文件”,开始录音。录音完成后,生成文件/sdcard/FinalAudio.amr
三、点击“中止录音”,中止录音,并显示录音输出文件以及该文件大小。
大体代码以下:
一、AudioRecord录音,封装成WAV格式
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
package
com.example.audiorecordtest;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileNotFoundException;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
android.media.AudioFormat;
import
android.media.AudioRecord;
public
class
AudioRecordFunc {
// 缓冲区字节大小
private
int
bufferSizeInBytes =
0
;
//AudioName裸音频数据文件 ,麦克风
private
String AudioName =
""
;
//NewAudioName可播放的音频文件
private
String NewAudioName =
""
;
private
AudioRecord audioRecord;
private
boolean
isRecord =
false
;
// 设置正在录制的状态
private
static
AudioRecordFunc mInstance;
private
AudioRecordFunc(){
}
public
synchronized
static
AudioRecordFunc getInstance()
{
if
(mInstance ==
null
)
mInstance =
new
AudioRecordFunc();
return
mInstance;
}
public
int
startRecordAndFile() {
//判断是否有外部存储设备sdcard
if
(AudioFileFunc.isSdcardExit())
{
if
(isRecord)
{
return
ErrorCode.E_STATE_RECODING;
}
else
{
if
(audioRecord ==
null
)
creatAudioRecord();
audioRecord.startRecording();
// 让录制状态为true
isRecord =
true
;
// 开启音频文件写入线程
new
Thread(
new
AudioRecordThread()).start();
return
ErrorCode.SUCCESS;
}
}
else
{
return
ErrorCode.E_NOSDCARD;
}
}
public
void
stopRecordAndFile() {
close();
}
public
long
getRecordFileSize(){
return
AudioFileFunc.getFileSize(NewAudioName);
}
private
void
close() {
if
(audioRecord !=
null
) {
System.out.println(
"stopRecord"
);
isRecord =
false
;
//中止文件写入
audioRecord.stop();
audioRecord.release();
//释放资源
audioRecord =
null
;
}
}
private
void
creatAudioRecord() {
// 获取音频文件路径
AudioName = AudioFileFunc.getRawFilePath();
NewAudioName = AudioFileFunc.getWavFilePath();
// 得到缓冲区字节大小
bufferSizeInBytes = AudioRecord.getMinBufferSize(AudioFileFunc.AUDIO_SAMPLE_RATE,
AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
// 建立AudioRecord对象
audioRecord =
new
AudioRecord(AudioFileFunc.AUDIO_INPUT, AudioFileFunc.AUDIO_SAMPLE_RATE,
AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes);
}
class
AudioRecordThread
implements
Runnable {
@Override
public
void
run() {
writeDateTOFile();
//往文件中写入裸数据
copyWaveFile(AudioName, NewAudioName);
//给裸数据加上头文件
}
}
/**
* 这里将数据写入文件,可是并不能播放,由于AudioRecord得到的音频是原始的裸音频,
* 若是须要播放就必须加入一些格式或者编码的头信息。可是这样的好处就是你能够对音频的 裸数据进行处理,好比你要作一个爱说话的TOM
* 猫在这里就进行音频的处理,而后从新封装 因此说这样获得的音频比较容易作一些音频的处理。
*/
private
void
writeDateTOFile() {
// new一个byte数组用来存一些字节数据,大小为缓冲区大小
byte
[] audiodata =
new
byte
[bufferSizeInBytes];
FileOutputStream fos =
null
;
int
readsize =
0
;
try
{
File file =
new
File(AudioName);
if
(file.exists()) {
file.delete();
}
fos =
new
FileOutputStream(file);
// 创建一个可存取字节的文件
}
catch
(Exception e) {
e.printStackTrace();
}
while
(isRecord ==
true
) {
readsize = audioRecord.read(audiodata,
0
, bufferSizeInBytes);
if
(AudioRecord.ERROR_INVALID_OPERATION != readsize && fos!=
null
) {
try
{
fos.write(audiodata);
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
try
{
if
(fos !=
null
)
fos.close();
// 关闭写入流
}
catch
(IOException e) {
e.printStackTrace();
}
}
// 这里获得可播放的音频文件
private
void
copyWaveFile(String inFilename, String outFilename) {
FileInputStream in =
null
;
FileOutputStream out =
null
;
long
totalAudioLen =
0
;
long
totalDataLen = totalAudioLen +
36
;
long
longSampleRate = AudioFileFunc.AUDIO_SAMPLE_RATE;
int
channels =
2
;
long
byteRate =
16
* AudioFileFunc.AUDIO_SAMPLE_RATE * channels /
8
;
byte
[] data =
new
byte
[bufferSizeInBytes];
try
{
in =
new
FileInputStream(inFilename);
out =
new
FileOutputStream(outFilename);
totalAudioLen = in.getChannel().size();
totalDataLen = totalAudioLen +
36
;
WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
longSampleRate, channels, byteRate);
while
(in.read(data) != -
1
) {
out.write(data);
}
in.close();
out.close();
}
catch
(FileNotFoundException e) {
e.printStackTrace();
}
catch
(IOException e) {
e.printStackTrace();
}
}
/**
* 这里提供一个头信息。插入这些信息就能够获得能够播放的文件。
* 为我为啥插入这44个字节,这个还真没深刻研究,不过你随便打开一个wav
* 音频的文件,能够发现前面的头文件能够说基本同样哦。每种格式的文件都有
* 本身特有的头文件。
*/
private
void
WriteWaveFileHeader(FileOutputStream out,
long
totalAudioLen,
long
totalDataLen,
long
longSampleRate,
int
channels,
long
byteRate)
throws
IOException {
byte
[] header =
new
byte
[
44
];
header[
0
] =
'R'
;
// RIFF/WAVE header
header[
1
] =
'I'
;
header[
2
] =
'F'
;
header[
3
] =
'F'
;
header[
4
] = (
byte
) (totalDataLen &
0xff
);
header[
5
] = (
byte
) ((totalDataLen >>
8
) &
0xff
);
header[
6
] = (
byte
) ((totalDataLen >>
16
) &
0xff
);
header[
7
] = (
byte
) ((totalDataLen >>
24
) &
0xff
);
header[
8
] =
'W'
;
header[
9
] =
'A'
;
header[
10
] =
'V'
;
header[
11
] =
'E'
;
header[
12
] =
'f'
;
// 'fmt ' chunk
header[
13
] =
'm'
;
header[
14
] =
't'
;
header[
15
] =
' '
;
header[
16
] =
16
;
// 4 bytes: size of 'fmt ' chunk
header[
17
] =
0
;
header[
18
] =
0
;
header[
19
] =
0
;
header[
20
] =
1
;
// format = 1
header[
21
] =
0
;
header[
22
] = (
byte
) channels;
header[
23
] =
0
;
header[
24
] = (
byte
) (longSampleRate &
0xff
);
header[
25
] = (
byte
) ((longSampleRate >>
8
) &
0xff
);
header[
26
] = (
byte
) ((longSampleRate >>
16
) &
0xff
);
header[
27
] = (
byte
) ((longSampleRate >>
24
) &
0xff
);
header[
28
] = (
byte
) (byteRate &
0xff
);
header[
29
] = (
byte
) ((byteRate >>
8
) &
0xff
);
header[
30
] = (
byte
) ((byteRate >>
16
) &
0xff
);
header[
31
] = (
byte
) ((byteRate >>
24
) &
0xff
);
header[
32
] = (
byte
) (
2
*
16
/
8
);
// block align
header[
33
] =
0
;
header[
34
] =
16
;
// bits per sample
header[
35
] =
0
;
header[
36
] =
'd'
;
header[
37
] =
'a'
;
header[
38
] =
't'
;
header[
39
] =
'a'
;
header[
40
] = (
byte
) (totalAudioLen &
0xff
);
header[
41
] = (
byte
) ((totalAudioLen >>
8
) &
0xff
);
header[
42
] = (
byte
) ((totalAudioLen >>
16
) &
0xff
);
header[
43
] = (
byte
) ((totalAudioLen >>
24
) &
0xff
);
out.write(header,
0
,
44
);
}
}
|
二、MediaRecorder录音,输出amr格式音频
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
|
package
com.example.audiorecordtest;
import
java.io.File;
import
java.io.IOException;
import
android.media.MediaRecorder;
public
class
MediaRecordFunc {
private
boolean
isRecord =
false
;
private
MediaRecorder mMediaRecorder;
private
MediaRecordFunc(){
}
private
static
MediaRecordFunc mInstance;
public
synchronized
static
MediaRecordFunc getInstance(){
if
(mInstance ==
null
)
mInstance =
new
MediaRecordFunc();
return
mInstance;
}
public
int
startRecordAndFile(){
//判断是否有外部存储设备sdcard
if
(AudioFileFunc.isSdcardExit())
{
if
(isRecord)
{
return
ErrorCode.E_STATE_RECODING;
}
else
{
if
(mMediaRecorder ==
null
)
createMediaRecord();
try
{
mMediaRecorder.prepare();
mMediaRecorder.start();
// 让录制状态为true
isRecord =
true
;
return
ErrorCode.SUCCESS;
}
catch
(IOException ex){
ex.printStackTrace();
return
ErrorCode.E_UNKOWN;
}
}
}
else
{
return
ErrorCode.E_NOSDCARD;
}
}
public
void
stopRecordAndFile(){
close();
}
public
long
getRecordFileSize(){
return
AudioFileFunc.getFileSize(AudioFileFunc.getAMRFilePath());
}
private
void
createMediaRecord(){
/* ①Initial:实例化MediaRecorder对象 */
mMediaRecorder =
new
MediaRecorder();
/* setAudioSource/setVedioSource*/
mMediaRecorder.setAudioSource(AudioFileFunc.AUDIO_INPUT);
//设置麦克风
/* 设置输出文件的格式:THREE_GPP/MPEG-4/RAW_AMR/Default
* THREE_GPP(3gp格式,H263视频/ARM音频编码)、MPEG-四、RAW_AMR(只支持音频且音频编码要求为AMR_NB)
*/
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
/* 设置音频文件的编码:AAC/AMR_NB/AMR_MB/Default */
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
/* 设置输出文件的路径 */
File file =
new
File(AudioFileFunc.getAMRFilePath());
if
(file.exists()) {
file.delete();
}
mMediaRecorder.setOutputFile(AudioFileFunc.getAMRFilePath());
}
private
void
close(){
if
(mMediaRecorder !=
null
) {
System.out.println(
"stopRecord"
);
isRecord =
false
;
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder =
null
;
}
}
}
|
1
|
|
三、其余文件
AudioFileFunc.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
|
package
com.example.audiorecordtest;
import
java.io.File;
import
android.media.MediaRecorder;
import
android.os.Environment;
public
class
AudioFileFunc {
//音频输入-麦克风
public
final
static
int
AUDIO_INPUT = MediaRecorder.AudioSource.MIC;
//采用频率
//44100是目前的标准,可是某些设备仍然支持22050,16000,11025
public
final
static
int
AUDIO_SAMPLE_RATE =
44100
;
//44.1KHz,广泛使用的频率
//录音输出文件
private
final
static
String AUDIO_RAW_FILENAME =
"RawAudio.raw"
;
private
final
static
String AUDIO_WAV_FILENAME =
"FinalAudio.wav"
;
public
final
static
String AUDIO_AMR_FILENAME =
"FinalAudio.amr"
;
/**
* 判断是否有外部存储设备sdcard
* @return true | false
*/
public
static
boolean
isSdcardExit(){
if
(Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
return
true
;
else
return
false
;
}
/**
* 获取麦克风输入的原始音频流文件路径
* @return
*/
public
static
String getRawFilePath(){
String mAudioRawPath =
""
;
if
(isSdcardExit()){
String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath();
mAudioRawPath = fileBasePath+
"/"
+AUDIO_RAW_FILENAME;
}
return
mAudioRawPath;
}
/**
* 获取编码后的WAV格式音频文件路径
* @return
*/
public
static
String getWavFilePath(){
String mAudioWavPath =
""
;
if
(isSdcardExit()){
String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath();
mAudioWavPath = fileBasePath+
"/"
+AUDIO_WAV_FILENAME;
}
return
mAudioWavPath;
}
/**
* 获取编码后的AMR格式音频文件路径
* @return
*/
public
static
String getAMRFilePath(){
String mAudioAMRPath =
""
;
if
(isSdcardExit()){
String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath();
mAudioAMRPath = fileBasePath+
"/"
+AUDIO_AMR_FILENAME;
}
return
mAudioAMRPath;
}
/**
* 获取文件大小
* @param path,文件的绝对路径
* @return
*/
public
static
long
getFileSize(String path){
File mFile =
new
File(path);
if
(!mFile.exists())
return
-
1
;
return
mFile.length();
}
}
|
四、其余文件
ErrorCode.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
|
package
com.example.audiorecordtest;
import
android.content.Context;
import
android.content.res.Resources.NotFoundException;
public
class
ErrorCode {
public
final
static
int
SUCCESS =
1000
;
public
final
static
int
E_NOSDCARD =
1001
;
public
final
static
int
E_STATE_RECODING =
1002
;
public
final
static
int
E_UNKOWN =
1003
;
public
static
String getErrorInfo(Context vContext,
int
vType)
throws
NotFoundException
{
switch
(vType)
{
case
SUCCESS:
return
"success"
;
case
E_NOSDCARD:
return
vContext.getResources().getString(R.string.error_no_sdcard);
case
E_STATE_RECODING:
return
vContext.getResources().getString(R.string.error_state_record);
case
E_UNKOWN:
default
:
return
vContext.getResources().getString(R.string.error_unknown);
}
}
}
|
五、string.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?
xml
version="1.0" encoding="utf-8"?>
<
resources
>
<
string
name="app_name">AudioRecordTest</
string
>
<
string
name="hello_world">测试AudioRecord,实现录音功能</
string
>
<
string
name="menu_settings">Settings</
string
>
<
string
name="view_record_wav">录音WAV文件</
string
>
<
string
name="view_record_amr">录音AMR文件</
string
>
<
string
name="view_stop">中止录音</
string
>
<
string
name="error_no_sdcard">没有SD卡,没法存储录音数据</
string
>
<
string
name="error_state_record">正在录音中,请先中止录音</
string
>
<
string
name="error_unknown">没法识别的错误</
string
>
</
resources
>
|
六、主程序MainActivity
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
package com.example.audiorecordtest;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private final static int FLAG_WAV = 0;
private final static int FLAG_AMR = 1;
private int mState = -1; //-1:没再录制,0:录制wav,1:录制amr
private Button btn_record_wav;
private Button btn_record_amr;
private Button btn_stop;
private TextView txt;
private UIHandler uiHandler;
private UIThread uiThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewByIds();
setListeners();
init();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
private void findViewByIds(){
btn_record_wav = (Button)this.findViewById(R.id.btn_record_wav);
btn_record_amr = (Button)this.findViewById(R.id.btn_record_amr);
btn_stop = (Button)this.findViewById(R.id.btn_stop);
txt = (TextView)this.findViewById(R.id.text);
}
private void setListeners(){
btn_record_wav.setOnClickListener(btn_record_wav_clickListener);
btn_record_amr.setOnClickListener(btn_record_amr_clickListener);
btn_stop.setOnClickListener(btn_stop_clickListener);
}
private void init(){
uiHandler = new UIHandler();
}
private Button.OnClickListener btn_record_wav_clickListener = new Button.OnClickListener(){
public void onClick(View v){
record(FLAG_WAV);
}
};
private Button.OnClickListener btn_record_amr_clickListener = new Button.OnClickListener(){
public void onClick(View v){
record(FLAG_AMR);
}
};
private Button.OnClickListener btn_stop_clickListener = new Button.OnClickListener(){
public void onClick(View v){
stop();
}
};
/**
* 开始录音
* @param mFlag,0:录制wav格式,1:录音amr格式
*/
private void record(int mFlag){
if(mState != -1){
Message msg = new Message();
Bundle b = new Bundle();// 存放数据
b.putInt("cmd",CMD_RECORDFAIL);
b.putInt("msg", ErrorCode.E_STATE_RECODING);
msg.setData(b);
uiHandler.sendMessage(msg); // 向Handler发送消息,更新UI
return;
}
int mResult = -1;
switch(mFlag){
case FLAG_WAV:
AudioRecordFunc mRecord_1 = AudioRecordFunc.getInstance();
mResult = mRecord_1.startRecordAndFile();
break;
case FLAG_AMR:
MediaRecordFunc mRecord_2 = MediaRecordFunc.getInstance();
mResult = mRecord_2.startRecordAndFile();
break;
}
if(mResult == ErrorCode.SUCCESS){
uiThread = new UIThread();
new Thread(uiThread).start();
mState = mFlag;
}else{
Message msg = new Message();
Bundle b = new Bundle();// 存放数据
b.putInt("cmd",CMD_RECORDFAIL);
b.putInt("msg", mResult);
msg.setData(b);
uiHandler.sendMessage(msg); // 向Handler发送消息,更新UI
}
}
/**
* 中止录音
*/
private void stop(){
if(mState != -1){
switch(mState){
case FLAG_WAV:
AudioRecordFunc mRecord_1 = AudioRecordFunc.getInstance();
mRecord_1.stopRecordAndFile();
break;
case FLAG_AMR:
MediaRecordFunc mRecord_2 = MediaRecordFunc.getInstance();
mRecord_2.stopRecordAndFile();
break;
}
if(uiThread != null){
uiThread.stopThread();
}
if(uiHandler != null)
uiHandler.removeCallbacks(uiThread);
Message msg = new Message();
Bundle b = new Bundle();// 存放数据
b.putInt("cmd",CMD_STOP);
b.putInt("msg", mState);
msg.setData(b);
uiHandler.sendMessageDelayed(msg,1000); // 向Handler发送消息,更新UI
mState = -1;
}
}
private final static int CMD_RECORDING_TIME = 2000;
private final static int CMD_RECORDFAIL = 2001;
private final static int CMD_STOP = 2002;
class UIHandler extends Handler{
public UIHandler() {
}
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.d("MyHandler", "handleMessage......");
super.handleMessage(msg);
Bundle b = msg.getData();
int vCmd = b.getInt("cmd");
switch(vCmd)
{
case CMD_RECORDING_TIME:
int vTime = b.getInt("msg");
MainActivity.this.txt.setText("正在录音中,已录制:"+vTime+" s");
break;
case CMD_RECORDFAIL:
int vErrorCode = b.getInt("msg");
String vMsg = ErrorCode.getErrorInfo(MainActivity.this, vErrorCode);
MainActivity.this.txt.setText("录音失败:"+vMsg);
break;
case CMD_STOP:
int vFileType = b.getInt("msg");
switch(vFileType){
case FLAG_WAV:
AudioRecordFunc mRecord_1 = AudioRecordFunc.getInstance();
long mSize = mRecord_1.getRecordFileSize();
MainActivity.this.txt.setText("录音已中止.录音文件:"+AudioFileFunc.getWavFilePath()+"\n文件大小:"+mSize);
break;
case FLAG_AMR:
MediaRecordFunc mRecord_2 = MediaRecordFunc.getInstance();
mSize = mRecord_2.getRecordFileSize();
MainActivity.this.txt.setText("录音已中止.录音文件:"+AudioFileFunc.getAMRFilePath()+"\n文件大小:"+mSize);
break;
}
break;
default:
break;
}
}
};
class UIThread implements Runnable {
int mTimeMill = 0;
boolean vRun = true;
public void stopThread(){
vRun = false;
}
public void run() {
while(vRun){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mTimeMill ++;
Log.d("thread", "mThread........"+mTimeMill);
Message msg = new Message();
Bundle b = new Bundle();// 存放数据
b.putInt("cmd",CMD_RECORDING_TIME);
b.putInt("msg", mTimeMill);
msg.setData(b);
MainActivity.this.uiHandler.sendMessage(msg); // 向Handler发送消息,更新UI
}
}
}
}
|
个人github地址:https://github.com/dongweiq/study
欢迎关注,欢迎star o(∩_∩)o 。有什么问题请邮箱联系 dongweiqmail@gmail.com qq714094450