SpeechRecognizer вызывает ANR … Мне нужна помощь с Android-речевым API

EDIT : Я должен был упомянуть об этом уже, но я запускаю этот код в службе. Все приложение включено / выключено кнопкой виджета и не имеет активности.


Обновление : я попытался подключить источники SDK к проекту, чтобы я мог получить более точное представление о том, где произошел сбой, но из его взглядов включены только публичные API-интерфейсы, что, по-видимому, делает их намного менее полезными. Может ли кто-нибудь предложить хотя бы отладочный подход для решения этой проблемы? Я как бы застрял.


Я пытаюсь использовать пакет распознавания речи Android для записи речи пользователя и перевода его в текст. К сожалению, когда я пытаюсь инициировать прослушивание, я получаю ошибку ANR, которая не указывает на что-то конкретное.

Как указывает API SpeechRecognizer, при попытке вызвать его из основного потока возникает бросок RuntimeException. Это заставило бы меня задаться вопросом, была ли обработка слишком требовательна … но я знаю, что для этой цели другие приложения используют API Android, и это, как правило, довольно быстро.

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

Вам не нужно создавать класс SpeechRecognizer самостоятельно, и вам не нужно внедрять RecognizerListener. Google сделал их публичными, чтобы они были хорошими, но они выглядят довольно сложными и, вероятно, для использования только экспертами.

Чтобы получить текст от речи пользователей, просто нужно использовать RecognizerIntent.ACTION_RECOGNIZE_SPEECH, чтобы запустить встроенную функцию распознавания речи, а затем дождаться, когда результат вернется в 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

Удачи.

Обязательно используйте разрешение RECORD_AUDIO.

Из службы вы должны создать распознаватель из петлителя, работающего в основном потоке. Также RecognizerIntent.EXTRA_RESULTS должен быть SpeechRecognizer.RESULTS_RECOGNITION.

Код psuedo:

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

Вместо getApplicationContext() используйте this (т. getApplicationContext() Ваш экземпляр службы). android.app.Service наследуется от контекста.

Вот проблема, с которой я столкнулся, что может быть связано с вашим. Я получал нуль, независимо от того, из этой строки:

  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.

В любом случае, я, скорее всего, не буду проверять этот сайт снова, но, пожалуйста, напишите мне, если у вас есть какие-либо вопросы, так как теперь у меня есть распознавание речи без каких-либо подсказок, звуковых сигналов или чего-то еще.

У меня это получилось, установив приложение Google Voice

Intereting Posts
MediaCodec с поверхностным входом: создание выходного сигнала Что лучше использовать несколько AsyncTask или HandlerThread (Pipeline Thread)? Android, как открыть фрагмент из элемента списка Независимо от того, связана ли связанная служба или настраиваемые потоки при загрузке? Дополнительное пространство между клавишей «Сводная панель инструментов» и кнопкой «Домой / Вверх» Как проверить, установлен ли будильник Android: как хранить данные во внутренней памяти? Основные различия между ОС Linux и мобильными ОС (Android) Показать диалоговое окно входящих сообщений для не-пользователей, таких как Allo Интеграция Flurry в одно и то же приложение на Android и iOS SetMicrophoneMute (boolean) не работает на некоторых устройствах Андроид mkdirs не работает Получить список зарегистрированных ожидающих намерений в ОС Android Не удалось найти конструктор андроида NDK r9 для mac Установка ActionBar Elevation на устройствах до 5.0 с помощью AppCompat