共计 2876 个字符,预计需要花费 8 分钟才能阅读完成。
移动端语音识别技术让智能助手、实时字幕等场景成为可能,大幅提升了人机交互效率。作为开发者,快速实现稳定可靠的语音转文本功能是增强应用竞争力的关键。

一、API 选型:SpeechRecognizer vs ML Kit
在 Android 平台上,我们主要面对两种语音识别方案选择:
- SpeechRecognizer(系统内置 API)
- 必须联网使用,依赖 Google 语音服务
- 延迟较高(通常 1 - 3 秒)但准确率优秀
-
免费且兼容 Android 4.1+ 设备
-
ML Kit 语音识别 API
- 支持离线模式(需下载约 200MB 模型文件)
- 延迟可控制在 800ms 内
- 需要 Firebase 依赖,部分高级功能收费
对于新手项目,建议优先使用 SpeechRecognizer 快速验证功能,后期再根据需求考虑迁移到 ML Kit。
二、基础实现全流程
1. 权限声明
在 AndroidManifest.xml 中添加:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
2. 动态权限申请
private fun checkAudioPermission() {
when {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.RECORD_AUDIO
) == PackageManager.PERMISSION_GRANTED -> {startVoiceRecognition()
}
ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.RECORD_AUDIO
) -> {showPermissionExplanationDialog()
}
else -> {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.RECORD_AUDIO),
AUDIO_PERMISSION_CODE
)
}
}
}
3. 音频配置核心参数
val audioFormat = AudioFormat.ENCODING_PCM_16BIT // 16 位采样
val sampleRate = 16000 // 16kHz 采样率
val channelConfig = AudioFormat.CHANNEL_IN_MONO // 单声道
val bufferSize = AudioRecord.getMinBufferSize(
sampleRate,
channelConfig,
audioFormat
) * 2 // 双倍缓冲
4. 完整语音识别示例
class SpeechActivity : AppCompatActivity() {
private lateinit var speechRecognizer: SpeechRecognizer
private val audioManager by lazy {getSystemService(AUDIO_SERVICE) as AudioManager }
override fun onCreate(savedInstanceState: Bundle?) {
//... 初始化视图
setupSpeechRecognizer()}
private fun setupSpeechRecognizer() {speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this).apply {
setRecognitionListener(object : RecognitionListener {override fun onResults(results: Bundle) {
val matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
matches?.firstOrNull()?.let { text ->
updateUI(text)
}
}
// 必须实现所有回调方法
override fun onError(error: Int) {when(error) {SpeechRecognizer.ERROR_NO_MATCH -> showToast("未识别到语音")
else -> showToast("识别错误代码: $error")
}
}
//... 其他回调省略
})
}
}
fun startListening() {
audioManager.requestAudioFocus(
focusChangeListener,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
)
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true)
}
speechRecognizer.startListening(intent)
}
}
三、性能优化实战
1. 内存管理策略
- 采用环形缓冲区处理音频流
- 每 2 秒强制 flush 一次识别请求
- 使用
WeakReference持有 Activity 引用
2. 超时重试机制
private var retryCount = 0
override fun onError(error: Int) {if(error == ERROR_SPEECH_TIMEOUT && retryCount < 3) {
retryCount++
Handler(Looper.getMainLooper()).postDelayed({ startListening() },
1000L
)
}
}
3. 内存泄漏检测
- 在 Android Studio 中打开 Profiler
- 选择 Memory 视图开始记录
- 反复进入 / 退出语音识别界面
- 观察 Activity 实例是否被正确回收
四、避坑指南
- 国产手机兼容性:
- 小米 / 华为等设备需要单独申请自启动权限
-
OPPO 系统会限制后台麦克风访问
-
电量优化:
- 使用
WorkManager调度后台识别任务 -
设置最长持续识别时间为 60 秒
-
数据安全:
- 敏感语音采用 AES-256 加密后存储
- 避免在日志中输出原始语音文本
五、进阶思考
当前基于云端 ASR 的通用模型对医疗、法律等专业术语识别较差。是否可以通过以下方式优化:
1. 在客户端预过滤行业关键词
2. 上传上下文语义辅助云端分析
3. 定制化微调 Transformer 模型
完整的语音识别系统就像训练一个耐心的倾听者——既要快速响应,又要准确理解。希望这篇指南能帮你避开我踩过的那些坑!
正文完
