注: 来自gpt生成, 已验证可用
要实现一个按钮用来控制开始和停止录音,并且录制 16 kHz 采样率的音频,保存为 PCM 格式的文件,你可以根据以下步骤来编写代码:
步骤 1: 在 AndroidManifest.xml
中添加权限
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
步骤 2: 检查并请求必要的运行时权限
在 Activity
中添加权限请求代码:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE},
0);
}
步骤 3: 创建 AudioRecord
实例并设置录音参数
int sampleRateInHz = 16000; // 采样率为 16 kHz
int channelConfig = AudioFormat.CHANNEL_IN_MONO; // 单声道
int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // PCM 16 位编码
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC,
sampleRateInHz,
channelConfig,
audioFormat,
bufferSizeInBytes);
步骤 4: 设置按钮的点击事件监听器以开始和停止录音
添加按钮控制代码:
Button recordButton = findViewById(R.id.record_button); // 假设按钮ID是 record_button
AtomicBoolean isRecording = new AtomicBoolean(false); // 用于在主线程和录音线程之间同步状态
recordButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isRecording.get()) {
// 停止录音
isRecording.set(false);
recordButton.setText("Start Recording");
} else {
// 开始录音
isRecording.set(true);
recordButton.setText("Stop Recording");
startRecording(audioRecord, bufferSizeInBytes, isRecording);
}
}
});
步骤 5: 开始录音并写入文件
private void startRecording(AudioRecord audioRecord, int bufferSizeInBytes, AtomicBoolean isRecording) {
Thread recordingThread = new Thread(new Runnable() {
@Override
public void run() {
File recordingFile = new File(getExternalFilesDir(null), "myRecording.pcm");
try (FileOutputStream fileOutputStream = new FileOutputStream(recordingFile)) {
byte[] buffer = new byte[bufferSizeInBytes];
audioRecord.startRecording();
while (isRecording.get()) {
// 从 AudioRecord 对象中读取音频数据到 buffer 中
int readResult = audioRecord.read(buffer, 0, buffer.length);
if (readResult < 0) {
// 处理错误情况(需要转换为运行时异常或处理逻辑)
throw new IllegalStateException("AudioRecord read failed: " + readResult);
}
// 将音频数据写入文件
fileOutputStream.write(buffer, 0, readResult);
}
audioRecord.stop();
audioRecord.release();
} catch (IOException e) {
// 处理文件写入错误
e.printStackTrace();
}
}
});
recordingThread.start();
}
注意事项
- 一定要在
Activity
的onRequestPermissionsResult
方法内处理权限请求的结果。 - 在 Android 6.0 (API 23) 及以上版本需要动态请求
RECORD_AUDIO
和WRITE_EXTERNAL_STORAGE
权限。 - 上述代码片段提供了直接写入文件的基本方式,可根据需要对错误处理和UI反馈作进一步的细化。
- 如果您的应用目标 API 级别为 Android 10 (API 29) 或更高,则可能需要适应外部存储访问的变化,考虑使用无需特定存储权限即可访问的应用私有目录,例如
Context.getExternalFilesDir()
。 - 录音文件采用未压缩的 PCM 格式,文件大小会比较大,所以请根据应用场景做合适的空间管理处理。
现在,当你点击按钮时,应用会根据按钮的状态开启或停止录音,并且录音的数据会保存为一个 PCM 文件。