Android语音识别实战:从零开始的完整代码实现

Android语音识别完整实现指南

一、语音识别技术概述

语音识别(Speech Recognition)是将人类语音转换为可读文本的技术,在Android平台主要通过SpeechRecognizer API实现。相比第三方SDK,原生API具有轻量级、无需网络依赖(部分模式)等优势,适合对隐私和性能要求较高的场景。

1.1 技术选型对比

方案 优点 缺点
原生API 无需额外依赖,支持离线识别 功能相对基础
Google ML Kit 识别准确率高,支持多语言 需要网络连接(部分功能)
第三方SDK 功能丰富(如语义理解) 增加包体积,可能涉及隐私风险

二、实现前的准备工作

2.1 添加必要权限

AndroidManifest.xml中添加:

  1. <uses-permission android:name="android.permission.RECORD_AUDIO" />
  2. <!-- 仅当需要网络识别时添加 -->
  3. <uses-permission android:name="android.permission.INTERNET" />

2.2 检查权限(Android 6.0+)

  1. private fun checkAudioPermission(): Boolean {
  2. return ContextCompat.checkSelfPermission(
  3. this,
  4. Manifest.permission.RECORD_AUDIO
  5. ) == PackageManager.PERMISSION_GRANTED
  6. }
  7. private fun requestAudioPermission() {
  8. ActivityCompat.requestPermissions(
  9. this,
  10. arrayOf(Manifest.permission.RECORD_AUDIO),
  11. REQUEST_AUDIO_PERMISSION
  12. )
  13. }

三、核心实现步骤

3.1 创建SpeechRecognizer实例

  1. private lateinit var speechRecognizer: SpeechRecognizer
  2. private lateinit var recognitionListener: RecognitionListener
  3. private fun initSpeechRecognizer() {
  4. speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this)
  5. recognitionListener = MyRecognitionListener()
  6. speechRecognizer.setRecognitionListener(recognitionListener)
  7. }
  8. class MyRecognitionListener : RecognitionListener {
  9. override fun onResults(results: Bundle?) {
  10. val matches = results?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
  11. matches?.let {
  12. val resultText = it[0] // 获取最可能的结果
  13. runOnUiThread { textView.text = resultText }
  14. }
  15. }
  16. // 其他必要方法实现(空实现即可)
  17. override fun onBeginningOfSpeech() {}
  18. override fun onEndOfSpeech() {}
  19. override fun onError(error: Int) {
  20. Log.e("SpeechError", "Error code: $error")
  21. }
  22. // ... 实现其他7个方法
  23. }

3.2 配置识别参数

  1. private fun startListening() {
  2. val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
  3. putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
  4. putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, packageName)
  5. putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5) // 返回最多5个候选结果
  6. // 离线识别配置(需设备支持)
  7. putExtra(RecognizerIntent.EXTRA_PREFER_OFFLINE, true)
  8. }
  9. speechRecognizer.startListening(intent)
  10. }

3.3 完整Activity示例

  1. class MainActivity : AppCompatActivity() {
  2. private lateinit var speechRecognizer: SpeechRecognizer
  3. private lateinit var btnSpeak: Button
  4. private lateinit var textView: TextView
  5. override fun onCreate(savedInstanceState: Bundle?) {
  6. super.onCreate(savedInstanceState)
  7. setContentView(R.layout.activity_main)
  8. btnSpeak = findViewById(R.id.btnSpeak)
  9. textView = findViewById(R.id.textView)
  10. if (!checkAudioPermission()) {
  11. requestAudioPermission()
  12. } else {
  13. initSpeechRecognizer()
  14. }
  15. btnSpeak.setOnClickListener {
  16. if (checkAudioPermission()) {
  17. startListening()
  18. } else {
  19. Toast.makeText(this, "需要录音权限", Toast.LENGTH_SHORT).show()
  20. }
  21. }
  22. }
  23. // ... 前文定义的权限检查和识别器初始化方法
  24. override fun onDestroy() {
  25. super.onDestroy()
  26. speechRecognizer.destroy() // 释放资源
  27. }
  28. }

四、高级功能实现

4.1 持续监听模式

  1. // 在RecognitionListener中处理部分结果
  2. override fun onPartialResults(partialResults: Bundle?) {
  3. val matches = partialResults?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
  4. matches?.let {
  5. val interimText = it[0]
  6. runOnUiThread { textView.text = interimText }
  7. }
  8. }
  9. // 修改启动参数
  10. private fun startContinuousListening() {
  11. val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
  12. putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true) // 启用部分结果
  13. // 其他配置...
  14. }
  15. speechRecognizer.startListening(intent)
  16. }

4.2 错误处理增强

  1. override fun onError(error: Int) {
  2. val errorMessage = when (error) {
  3. SpeechRecognizer.ERROR_AUDIO -> "音频录制错误"
  4. SpeechRecognizer.ERROR_CLIENT -> "客户端错误"
  5. SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS -> "权限不足"
  6. SpeechRecognizer.ERROR_NETWORK -> "网络错误"
  7. SpeechRecognizer.ERROR_NO_MATCH -> "未识别到语音"
  8. SpeechRecognizer.ERROR_RECOGNIZER_BUSY -> "识别服务忙"
  9. SpeechRecognizer.ERROR_SERVER -> "服务器错误"
  10. SpeechRecognizer.ERROR_SPEECH_TIMEOUT -> "无语音输入"
  11. else -> "未知错误"
  12. }
  13. runOnUiThread {
  14. Toast.makeText(this, "识别错误: $errorMessage", Toast.LENGTH_SHORT).show()
  15. }
  16. }

五、性能优化建议

  1. 资源管理

    • onPause()中调用speechRecognizer.cancel()
    • onDestroy()中调用speechRecognizer.destroy()
  2. 识别参数调优

    1. // 针对短语音优化
    2. intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 1000)
    3. intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, 1000)
  3. 多语言支持

    1. // 设置中文识别
    2. intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "zh-CN")
    3. // 或支持多种语言
    4. intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "zh-CN,en-US")

六、完整项目结构建议

  1. app/
  2. ├── src/
  3. ├── main/
  4. ├── java/com/example/speech/
  5. ├── MainActivity.kt
  6. ├── SpeechHelper.kt // 封装识别逻辑
  7. └── SpeechListener.kt // 自定义监听器
  8. └── res/
  9. ├── layout/activity_main.xml
  10. └── values/strings.xml
  11. └── AndroidManifest.xml
  12. └── build.gradle

七、常见问题解决方案

  1. 无识别结果

    • 检查麦克风权限
    • 增加EXTRA_MAX_RESULTS
    • 测试不同语言模型
  2. 识别延迟高

    • 启用离线模式(如果设备支持)
    • 减少返回结果数量
    • 优化音频输入参数
  3. 服务不可用

    • 检查设备是否支持语音识别:
      1. val isAvailable = SpeechRecognizer.isRecognitionAvailable(this)

八、扩展功能建议

  1. 结合NLP处理:将识别结果传递给NLP引擎进行语义分析
  2. 语音指令系统:定义特定语音命令触发操作
  3. 实时字幕:在视频播放时显示实时语音转文字

通过以上实现,开发者可以快速在Android应用中集成功能完善的语音识别能力。实际开发中,建议将识别逻辑封装为独立模块,便于复用和维护。