SpeechRecognizer 导致 ANR...我需要 Android 语音 API 方面的帮助

发布于 2024-10-09 12:52:52 字数 2346 浏览 0 评论 0原文

编辑:我应该已经提到过这一点,但我正在服务中运行此代码。整个应用程序通过小部件按钮打开/关闭,并且没有任何活动。


更新:我尝试将 SDK 源附加到项目中,以便可以更准确地了解故障发生的位置,但来自 它的外观,只有公共 API包括在内,这似乎使它们变得不太有用......任何人都可以建议至少一种调试方法来解决这个问题吗?我有点卡住了。


我正在尝试使用 Android 的 语音识别包 来记录用户语音并将其翻译为文本。不幸的是,当我尝试启动监听时,我收到一个 ANR 错误,该错误没有指出任何具体内容。

正如 SpeechRecognizer API 所示,如果您尝试从主线程调用它,则会抛出 RuntimeException。这让我怀疑处理是否要求太高了……但我知道其他应用程序使用 Android API 来实现此目的,而且它通常非常快速。

java.lang.RuntimeException:SpeechRecognizer 只能从应用程序的主线程使用

这是我尝试从服务调用的代码的(经过修剪的)示例。这是正确的方法吗?

感谢您抽出时间提供帮助。这一直是我至今无法逾越的坎。

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);

EDIT: I should have mentioned this already, but I'm running this code in a service. The entire app is turned on/off by a widget button and has no activity.


Update: I tried attaching the SDK sources to the project so I could get a more precise idea of where the failure was occurring, but from the looks of it, only public APIs are included, which seems to make them a lot less useful... can anyone suggest at least a debugging approach for solving this issue? I'm kind of stuck.


I'm trying to use Android's speech recognition package to record user speech and translate it to text. Unfortunately, when I attempt initiate listening, I get an ANR error that doesn't point to anything specific.

As the SpeechRecognizer API indicates, a RuntimeException is thrown if you attempt to call it from the main thread. This would make me wonder if the processing was just too demanding... but I know that other applications use the Android API for this purpose and it is typically pretty snappy.

java.lang.RuntimeException: SpeechRecognizer should be used only from the application's main thread

Here is a (trimmed) sample of the code I'm trying to call from my service. Is this the proper approach?

Thanks for taking the time to help. This has been a hurdle I haven't been able to get over yet.

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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

呢古 2024-10-16 12:52:52

确保使用 RECORD_AUDIO 权限。

Make Sure to use the RECORD_AUDIO permission.

冬天旳寂寞 2024-10-16 12:52:52

您不需要自己创建 SpeechRecognizer 类,也不需要实现 RecognizerListener。谷歌将它们公开是为了友善,但它们看起来相当复杂,可能仅供专家使用。

要从用户语音中获取文本,您只需使用 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祝

你好运。

You shouldn't need to create the SpeechRecognizer class yourself, nor do you need to implement a RecognizerListener. Google made them public to be nice, but they look pretty complicated and probably for use by experts only.

To get text from the users speech yo simply need to use the RecognizerIntent.ACTION_RECOGNIZE_SPEECH to launch the built-in speech recognizer Activity and then wait for the result to come back in onActivityResult. Take a look at the example code here:

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/VoiceRecognition.html

I pulled it from this article.

http://developer.android.com/resources/articles/speech-input.html

Good Luck.

林空鹿饮溪 2024-10-16 12:52:52

从服务中,您必须从主线程上运行的循环程序创建识别器。此外,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);

From a service, you have to create the recognizer from looper running on the main thread. Also RecognizerIntent.EXTRA_RESULTS should be SpeechRecognizer.RESULTS_RECOGNITION.

psuedo code:

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);
长亭外,古道边 2024-10-16 12:52:52

使用 this (即您的服务实例),而不是 getApplicationContext()android.app.Service 继承自 Context。

Instead of getApplicationContext(), use this (i.e. your service instance). android.app.Service inherits from Context.

ゝ偶尔ゞ 2024-10-16 12:52:52

这是我遇到的问题,可能与你的问题有关。不管怎样,我从这一行得到了空值:

  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 时则不然。

不管怎样,我很可能不会再检查这个网站,但如果你有任何问题,请给我发电子邮件,因为我现在确实可以进行语音识别,没有任何提示、蜂鸣声或其他任何东西。

Here is the problem I ran into, which might be related to yours. I was getting null, no matter what, from this line:

  ArrayList<String> voiceResults = results                .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);  

Changing it to this completely fixed the problem:

  ArrayList<String> voiceResults = results                .getStringArrayList("results_recognition");  

I printed out the keyset from the bundle, and that was the only value. Note that the value of "results_recognition" is not the value of the string stored at RecognizerIntent.EXTRA_RESULTS. I think that's a bug, or at least it should be, since using RecognizerIntent.EXTRA_RESULTS works fine in the Activity way of doing speech recognition, but not when someone uses SpeechRecognizer.

Anyways, i most likely won't check this website again, but please email me if you have any questions, since I now do have speech recognition working without any prompts, beeps, or anything else.

你怎么这么可爱啊 2024-10-16 12:52:52

我通过安装 Google Voice 应用程序来实现此功能

I got this to work by installing the Google Voice App

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文