2010-12-30 2 views
11

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


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


Я пытаюсь использовать андроида speech recognition package записи пользователя речь и переводить его в текст. К сожалению, когда я пытаюсь инициировать прослушивание, я получаю ошибку 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); 
+0

Программное обеспечение тег развития является своего рода излишним ;-) Это больше для темы говорить о поле в целом. – SapphireSun

+0

Спасибо, это имеет смысл. – tnunamak

ответ

4

Вы не должны создать класс 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

Good Luck.

+1

Это была дорога, с которой я начал. Я пошел с подходом SpeechRecognizer, потому что я запускаю все за кулисами в службе ... мне не показалось правильным запустить Activity, если у моего приложения не было фокуса (он работает в фоновом режиме). Если дело доходит до этого, мне просто придется использовать Activity в любом случае. Мое приложение предназначено для использования без взаимодействия с пользователем на экране. – tnunamak

+0

Из того, что я прочитал до сих пор, API распознавания речи - это просто интерфейс и что реализация фактически живет где-то в другом месте, например, приложение «Голосовой поиск». Я считаю, что он основан на проприетарной технологии и не является открытым исходным кодом. Похоже, вы на милость предоставленного интерфейса. – satur9nine

+0

Это звучит правильно для меня, но я думаю, что в моем коде есть какой-то недостаток дизайна, потому что мое намерение должно обрабатываться тем же приложением/действием, которое будет использоваться, если я буду транслировать свое намерение с помощью startActivityForResult(). Реализация должна влиять на обе методики одинаково ... Я думаю, что я, вероятно, просто займусь деятельностью как альтернативное решение. – tnunamak

1

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

1

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

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.

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

+0

Для этого вам необходимо: распознаватьIntent.putExtra (RecognizerIntent.EXTRA_CALLING_PACKAGE, «Your.package»); распознавательIntent.putExtra (RecognizerIntent.EXTRA_PARTIAL_RESULTS, true); – gregm

+0

Используйте getStringArrayList (SpeechRecognizer.RESULTS_RECOGNITION) вместо строчной кодированной строки –

1

Я получил эту работу путем установки Google Voice App

4

Убедитесь, что использовать разрешение RECORD_AUDIO.

3

Из службы вы должны создать распознаватель из петлителя, работающего по основному потоку. Также 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);