Android语音转文本字符串匹配计数功能实现求助
语音转文本后对比文本统计相同内容数量的解决方案
原代码存在的问题
- 对比逻辑执行时机错误:在调用
startActivityForResult后立即执行对比,此时语音识别尚未完成,tvText内容为空,无法得到有效结果。 - 循环边界错误:内层循环使用
s1.length()作为终止条件,应该使用s2.length(),否则会出现数组越界或漏匹配的情况。 - 字符重复统计:直接嵌套循环对比字符会重复计算同一字符的匹配次数(比如目标文本中的同一个字符多次匹配语音文本中的同一字符),不符合常规统计需求。
- Intent参数错误:重复设置
EXTRA_LANGUAGE,提示语应该使用EXTRA_PROMPT参数。
修正后的完整代码
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.speech.RecognizerIntent; import android.util.Log; import android.view.View; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.Map; import java.util.Set; public class Mic extends AppCompatActivity { protected static final int RESULT_SPEECH = 1000; private ImageButton btnspeak; private TextView tvText, tvText1; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mic); tvText1 = findViewById(R.id.textView7); tvText = findViewById(R.id.tvText); btnspeak = findViewById(R.id.btnspeak); btnspeak.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault()); // 修正提示语参数 intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Hi Speak Something"); try { tvText.setText(""); startActivityForResult(intent, RESULT_SPEECH); } catch (ActivityNotFoundException e) { Toast.makeText(getApplicationContext(), "Your device doesn't support speech to text", Toast.LENGTH_LONG).show(); e.printStackTrace(); } } }); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case RESULT_SPEECH: if (resultCode == Activity.RESULT_OK && null != data) { ArrayList<String> text = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); String speechResult = text.get(0); tvText.setText(speechResult); // 语音识别完成后再执行对比统计 String targetText = tvText1.getText().toString().trim(); if (!targetText.isEmpty() && !speechResult.isEmpty()) { int matchCount = calculateMatchCount(targetText, speechResult); // 显示统计结果,可替换为其他展示方式 Toast.makeText(this, "相同内容数量:" + matchCount, Toast.LENGTH_SHORT).show(); Log.d("MatchCount", "相同内容数量:" + matchCount); } } break; } } /** * 计算两个文本的相同内容数量,支持字符级和单词级两种统计方式 * @param targetText 目标文本(tvText1的内容) * @param speechResult 语音识别结果文本(tvText的内容) * @return 相同内容的数量 */ private int calculateMatchCount(String targetText, String speechResult) { // --- 方式1:字符级统计(统计每个字符在两个文本中出现的最小次数之和)--- Map<Character, Integer> targetCharCount = new HashMap<>(); for (char c : targetText.toCharArray()) { targetCharCount.put(c, targetCharCount.getOrDefault(c, 0) + 1); } Map<Character, Integer> speechCharCount = new HashMap<>(); for (char c : speechResult.toCharArray()) { speechCharCount.put(c, speechCharCount.getOrDefault(c, 0) + 1); } int matchCount = 0; for (Map.Entry<Character, Integer> entry : targetCharCount.entrySet()) { char c = entry.getKey(); if (speechCharCount.containsKey(c)) { matchCount += Math.min(entry.getValue(), speechCharCount.get(c)); } } // --- 方式2:单词级统计(按空格分割单词,统计相同单词数量,可忽略大小写)--- /* String[] targetWords = targetText.trim().split("\\s+"); String[] speechWords = speechResult.trim().split("\\s+"); Set<String> targetWordSet = new HashSet<>(Arrays.asList(targetWords)); int matchCount = 0; for (String word : speechWords) { String lowerWord = word.toLowerCase(); if (targetWordSet.contains(lowerWord)) { matchCount++; // 如果需要去重统计(同一单词只算一次),取消下面注释 // targetWordSet.remove(lowerWord); } } */ return matchCount; } }
说明
- 对比逻辑移至
onActivityResult方法,确保语音识别完成后再执行统计。 - 提供了两种统计方式:字符级和单词级,可根据需求注释/启用对应代码块。
- 修正了Intent的提示语参数,避免覆盖语言设置。
- 使用
trim()处理文本,避免空字符干扰统计。
内容的提问来源于stack exchange,提问作者Suji
相关产品推荐
相关产品推荐

