SpeechRecognizer 导致 ANR...我需要有关 Android 语音 API 的帮助
Posted
技术标签:
【中文标题】SpeechRecognizer 导致 ANR...我需要有关 Android 语音 API 的帮助【英文标题】:SpeechRecognizer causes ANR... I need help with Android speech API 【发布时间】:2011-06-01 09:20:51 【问题描述】:编辑:我应该已经提到了这一点,但我正在服务中运行此代码。整个应用由一个小部件按钮打开/关闭,并且没有任何活动。
更新:我尝试将 SDK 源附加到项目中,以便更准确地了解故障发生的位置,但从 the looks of it 开始,仅包含公共 API,这似乎使它们变得不那么有用...任何人都可以建议至少一种调试方法来解决此问题吗?我有点卡住了。
我正在尝试使用 android 的 speech recognition package 记录用户语音并将其翻译成文本。不幸的是,当我尝试启动监听时,我收到了一个 ANR 错误,它没有指向任何特定的内容。
正如 SpeechRecognizer API 所指出的,如果您尝试从主线程调用 RuntimeException,则会引发 RuntimeException。这让我想知道处理是否过于苛刻......但我知道其他应用程序为此目的使用 Android API,而且它通常非常快速。
java.lang.RuntimeException: SpeechRecognizer should be used only from the application's main thread
这是我试图从我的服务中调用的代码的(修剪过的)示例。这是正确的方法吗?
感谢您抽出宝贵时间提供帮助。这一直是我无法克服的障碍。
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
"com.domain.app");
SpeechRecognizer recognizer = SpeechRecognizer
.createSpeechRecognizer(this.getApplicationContext());
RecognitionListener listener = new RecognitionListener()
@Override
public void onResults(Bundle results)
ArrayList<String> voiceResults = results
.getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
if (voiceResults == null)
Log.e(getString(R.string.log_label), "No voice results");
else
Log.d(getString(R.string.log_label), "Printing matches: ");
for (String match : voiceResults)
Log.d(getString(R.string.log_label), match);
@Override
public void onReadyForSpeech(Bundle params)
Log.d(getString(R.string.log_label), "Ready for speech");
@Override
public void onError(int error)
Log.d(getString(R.string.log_label),
"Error listening for speech: " + error);
@Override
public void onBeginningOfSpeech()
Log.d(getString(R.string.log_label), "Speech starting");
;
recognizer.setRecognitionListener(listener);
recognizer.startListening(intent);
【问题讨论】:
软件开发标签有点多余 ;-) 这更适用于讨论该领域的主题。 【参考方案1】:确保使用 RECORD_AUDIO 权限。
【讨论】:
【参考方案2】:您不需要自己创建 SpeechRecognizer 类,也不需要实现 RecognizerListener。 Google 将它们公开是为了很好,但它们看起来很复杂,可能仅供专家使用。
要从用户语音中获取文本,您只需使用 RecognizerIntent.ACTION_RECOGNIZE_SPEECH 启动内置语音识别器 Activity,然后在 onActivityResult 中等待结果返回。看看这里的示例代码:
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/VoiceRecognition.html
我从这篇文章中提取出来的。
http://developer.android.com/resources/articles/speech-input.html
祝你好运。
【讨论】:
这就是我开始的道路。我选择了 SpeechRecognizer 方法,因为我在 Service 的幕后运行所有内容……如果我的应用程序没有焦点(它在后台运行),启动 Activity 似乎不正确。如果归根结底,我可能不得不使用一个活动。我的应用程序旨在无需用户在屏幕上进行交互即可使用。 从我目前所读到的内容来看,语音识别 API 只是一个接口,它的实现实际上存在于其他地方,例如“语音搜索”应用程序。我相信它是基于专有技术而不是开源的。看起来您受制于所提供的界面。 这听起来对我来说是正确的,但我认为我的代码中存在某种设计缺陷,因为我的意图应该由与广播我的意图相同的应用程序/活动来处理使用 startActivityForResult()。实现应该同样影响这两种技术......我想我可能会选择一个活动作为替代解决方案。【参考方案3】:从服务中,您必须从在主线程上运行的 looper 创建识别器。此外,RecognizerIntent.EXTRA_RESULTS 应该是 SpeechRecognizer.RESULTS_RECOGNITION。
伪代码:
public class VoiceRecognition implements RecognitionListener, Runnable
@Override
public void run()
recognizer = SpeechRecognizer.createSpeechRecognizer(yourContext);
recognizer.setRecognitionListener((RecognitionListener) this);
intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
//... all the intent stuff ...
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);
recognizer.startListening(intent);
@Override
public void onResults(Bundle results)
ArrayList<String> matches;
matches=results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
....
VoiceRecognition voiceRecognizer = new VoiceRecognition();
Handler loopHandler = new Handler(Looper.getMainLooper());
loopHandler.post(voiceRecognizer);
【讨论】:
【参考方案4】:使用this
(即您的服务实例)代替getApplicationContext()
。 android.app.Service
继承自 Context。
【讨论】:
【参考方案5】:这是我遇到的问题,可能与您的问题有关。无论如何,从这一行我得到了空值:
ArrayList<String> voiceResults = results .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
将其更改为完全解决了问题:
ArrayList<String> voiceResults = results .getStringArrayList("results_recognition");
我从捆绑包中打印出密钥集,这是唯一的值。请注意,“results_recognition”的值不是存储在 RecognizerIntent.EXTRA_RESULTS 中的字符串的值。我认为这是一个错误,或者至少应该是,因为使用 RecognizerIntent.EXTRA_RESULTS 在进行语音识别的 Activity 方式中可以正常工作,但在有人使用 SpeechRecognizer 时就不行。
无论如何,我很可能不会再查看此网站,但如果您有任何问题,请给我发电子邮件,因为我现在确实可以在没有任何提示、哔哔声或其他任何东西的情况下进行语音识别。
【讨论】:
你需要这个:recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, "Your.package"); identifyrIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true); 使用 getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION) 代替硬编码字符串【参考方案6】:我通过安装 Google Voice 应用程序来实现这一点
【讨论】:
以上是关于SpeechRecognizer 导致 ANR...我需要有关 Android 语音 API 的帮助的主要内容,如果未能解决你的问题,请参考以下文章
Android 进阶——性能优化之因Handler引起句柄泄漏导致ANR的定位和解决
Android 进阶——性能优化之因Handler引起句柄泄漏导致ANR的定位和解决