一、技术选型与核心原理
在Android Studio中实现语音转文字功能,核心依赖是Google提供的Speech-to-Text API(原Android Speech Recognition API)。该API通过设备内置的语音识别引擎或云端服务将音频流转换为文本,支持实时识别和离线模式(需设备支持)。开发者可通过RecognizerIntent或直接集成SpeechRecognizer类实现功能,其中后者提供更灵活的音频流控制和结果回调。
1.1 两种实现方式对比
| 实现方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| RecognizerIntent | 简单需求(如单次识别) | 代码量少,快速集成 | 界面不可定制,功能受限 |
| SpeechRecognizer | 复杂需求(如实时转写) | 支持连续识别、自定义UI | 需处理更多状态管理 |
二、环境准备与权限配置
2.1 添加依赖与权限
在AndroidManifest.xml中声明必要权限:
<uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.INTERNET" /> <!-- 云端识别需此权限 -->
对于Android 10及以上版本,需动态申请RECORD_AUDIO权限:
private fun checkAudioPermission() {if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.RECORD_AUDIO),REQUEST_RECORD_AUDIO_PERMISSION)}}
2.2 设备兼容性检查
部分旧设备可能不支持离线识别,需通过SpeechRecognizer.isRecognitionAvailable()检测:
val recognizer = SpeechRecognizer.createSpeechRecognizer(context)if (!recognizer.isRecognitionAvailable(context)) {Toast.makeText(context, "当前设备不支持语音识别", Toast.LENGTH_SHORT).show()}
三、核心代码实现
3.1 使用SpeechRecognizer实现实时转写
class SpeechToTextManager(private val context: Context) {private var speechRecognizer: SpeechRecognizer? = nullprivate var recognitionListener: RecognitionListener? = nullfun startListening() {speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context)recognitionListener = object : RecognitionListener {override fun onResults(results: Bundle?) {val matches = results?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)matches?.firstOrNull()?.let { text ->// 处理识别结果Log.d("STT", "识别结果: $text")}}// 其他回调方法...}speechRecognizer?.setRecognitionListener(recognitionListener)val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, context.packageName)speechRecognizer?.startListening(intent)}fun stopListening() {speechRecognizer?.stopListening()speechRecognizer?.destroy()}}
3.2 音频流处理优化
对于长语音场景,需通过AudioRecord直接采集音频并分块传输:
private fun startAudioRecord() {val sampleRate = 16000 // 推荐16kHz采样率val bufferSize = AudioRecord.getMinBufferSize(sampleRate,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT)val audioRecord = AudioRecord(MediaRecorder.AudioSource.MIC,sampleRate,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT,bufferSize)audioRecord.startRecording()val buffer = ByteArray(bufferSize)while (isRecording) {val bytesRead = audioRecord.read(buffer, 0, bufferSize)if (bytesRead > 0) {// 将buffer发送至识别服务sendAudioChunk(buffer)}}audioRecord.stop()audioRecord.release()}
四、性能优化策略
4.1 降噪处理
使用WebrtcAudioProcessor进行前端降噪:
// 在初始化时添加音频处理器val audioProcessor = WebRtcAudioProcessor()audioProcessor.setEchoCancelerEnabled(true)audioProcessor.setNoiseSuppressorEnabled(true)
4.2 网络请求优化
- 分块传输:将音频按500ms间隔分割,减少单次请求延迟
- 协议选择:优先使用WebSocket实现长连接,替代短连接HTTP
- 压缩算法:采用OPUS编码(64kbps)替代PCM,减少30%数据量
4.3 离线识别方案
对于无网络场景,可集成CMUSphinx开源引擎:
implementation 'edu.cmu.pocketsphinx:pocketsphinx-android:5prealpha@aar'
配置步骤:
- 将声学模型(
en-us-ptm)和语言模型(digitt.dic)放入assets目录 - 初始化配置:
val config = Config()config.setString("-hmm", "assets/en-us-ptm")config.setString("-dict", "assets/digitt.dic")val decoder = Decoder.defaultConfig(config)
五、常见问题解决方案
5.1 识别延迟过高
- 检查采样率是否匹配(云端服务推荐16kHz)
- 减少音频缓冲区大小(从1024降至512)
- 启用服务端流式识别(Google Cloud Speech-to-Text支持)
5.2 识别准确率低
- 添加语言检测:
val languageDetector = LanguageDetector.Builder().setLanguages(arrayOf("zh-CN", "en-US")).build()
- 使用领域适配:在Intent中添加专业领域参数:
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH) // 通用场景// 或intent.putExtra(RecognizerIntent.EXTRA_ONLY_RETURN_LANGUAGE_PREFERENCE, true)
5.3 内存泄漏处理
确保在Activity销毁时释放资源:
override fun onDestroy() {super.onDestroy()speechRecognizer?.cancel()speechRecognizer?.destroy()audioRecord?.release()}
六、进阶功能扩展
6.1 说话人分离
集成TensorFlow Lite实现多说话人检测:
val interpreter = Interpreter(loadModelFile(context))val input = convertAudioToTensorInput(audioBuffer)val output = Array(1) { FloatArray(2) } // 2个说话人interpreter.run(input, output)
6.2 实时字幕显示
结合RecyclerView实现动态文本更新:
class SubtitleAdapter : RecyclerView.Adapter<SubtitleViewHolder>() {private val items = mutableListOf<String>()fun addText(text: String) {items.add(text)notifyItemInserted(items.size - 1)// 保持最多5行if (items.size > 5) {items.removeAt(0)notifyItemRemoved(0)}}}
七、测试与调优
7.1 自动化测试方案
使用Espresso编写UI测试:
@Testfun testSpeechRecognition() {// 模拟语音输入(需配合Mock库)onView(withId(R.id.btnStart)).perform(click())// 验证结果展示onView(withText("测试文本")).check(matches(isDisplayed()))}
7.2 性能基准测试
关键指标:
| 指标 | 目标值 | 测量方法 |
|———|————|—————|
| 首字延迟 | <800ms | 从开始录音到首次结果返回 |
| 识别准确率 | >90% | 对比标准文本库 |
| 内存占用 | <30MB | Android Profiler监测 |
通过本文的完整实现方案,开发者可在Android Studio中快速构建稳定的语音转文字功能,覆盖从基础集成到高级优化的全流程需求。实际开发中,建议根据具体场景选择云端或离线方案,并持续通过用户反馈迭代优化识别模型。