2012-08-01 24 views
14

Para cualquiera que use el voice recognition API de Android, solía haber un práctico RecognitionListener que podría registrar varios eventos en sus callbacks. En particular, hubo el onBufferReceived(byte[]) método siguiente:¿Por qué RecognitionListener dejó de funcionar en JellyBean?

public abstract void onBufferReceived (byte[] buffer)

desde: Nivel API 8 Más sonido ha sido recibido. El propósito de esta función es permitir la retroalimentación al usuario con respecto al audio capturado . No hay garantía de que se llame a este método.

Parámetrosbuffer un tampón que contiene una secuencia de-big endian 16 bits números enteros que representan un flujo de audio de canal único. La frecuencia de muestreo depende de la implementación.

Aunque el método establece explícitamente que no hay garantía se va a llamar, en el ICS y antes de que efectivamente se llamaría el 100% del tiempo: con suficiente regularidad, al menos, de que mediante la concatenación de todos los bytes recibido de esta manera, podría reconstruir toda la secuencia de audio y reproducirla.

Por alguna razón, sin embargo, en el Jellybean SDK, mágicamente dejó de funcionar. No hay notificación de obsolescencia y el código aún se compila, pero el onBufferReceived ahora es nunca llamado. Técnicamente, esto no está rompiendo su API (ya que dice que "no hay garantía" de que se llame al método), pero claramente este es un cambio radical para muchas cosas que dependen de este comportamiento.

¿Alguien sabe por qué esta funcionalidad fue deshabilitada, y si hay una manera de replicar su comportamiento en Jellybean?

Aclaración: Me dan cuenta de que todo el RecognizerIntent cosa es una interfaz con múltiples implementaciones (incluyendo algunos disponibles en la Play Store), y que cada uno puede elegir qué hacer con RecognitionListener. Me refiero específicamente a la implementación predeterminada de Google que usa la gran mayoría de los teléfonos de Jellybean.

Respuesta

8

Google no llama a este método su aplicación de voz Jelly Bean (QuickSearchBox). Simplemente no está en el código. A menos que haya un comentario oficial de un Ingeniero de Google, no puedo dar una respuesta definitiva "por qué" lo hicieron. Busqué en los foros de desarrolladores pero no vi ningún comentario sobre esta decisión.

El valor predeterminado para el reconocimiento de voz viene de Google's VoiceSearch.apk. Puede descompilar esta aplicación y ver y buscar para ver que hay una Actividad para manejar una intención de acción * android.speech.action.RECOGNIZE_SPEECH *. En esta aplicación busqué "onBufferReceived" y encontré una referencia en com.google.android.voicesearch.GoogleRecognitionService $ RecognitionCallback.

Con Jelly Bean, Google renombró VoiceSearch.apk a QuickSearch.apk e hizo muchas nuevas adiciones a la aplicación (por ejemplo, dictado fuera de línea). Esperaría aún encontrar una llamada onBufferReceived, pero por alguna razón ya no existe.

+0

Gracias por el análisis en profundidad que confirma que el problema es universal en Jellybean :) Supongo que la única forma en que puede ser más definitivo es si conseguimos que un ingeniero de Google explique por qué ocurrió esto. ¡Gracias! –

2

Yo también estaba usando el método onBufferReceived y me decepcionó que la llamada (no garantizada) al método se descartara en Jelly Bean. Bueno, si no podemos tomar el audio con onBufferReceived(), tal vez exista la posibilidad de ejecutar un AudioRecord simultáneamente con el reconocimiento de voz. ¿Alguien intentó esto? Si no, lo haré girar e informaré.

+2

Dudo que sea posible, pero me encantaría escuchar sus resultados. –

+5

Bueno, lo probé bien, pero parece que ejecutar un AudioRecord y SpeechRecognizer al mismo tiempo no funcionará. Solo uno de ellos puede acceder al micrófono. Entonces, de vuelta a la necesidad de que onBufferReceived() funcione ... ¡vamos a Google, hazlo! –

0

Corrí hacia el mismo problema. La razón por la que no solo acepté que "esto no funciona" era porque Google Nows "se nota a sí mismo" graba el audio y se lo envía. Lo que descubrí en Logcat mientras se ejecuta el -operación "-nota-a sí mismo" era:

02-20 14:04:59.664: I/AudioService(525): AudioFocus requestAudioFocus() from [email protected][email protected] 

02-20 14:04:59.754: I/AbstractCardController.SelfNoteController(8675): #attach 
02-20 14:05:01.006: I/AudioService(525): AudioFocus abandonAudioFocus() from [email protected][email protected] 

02-20 14:05:05.791: I/ActivityManager(525): START u0 {act=com.google.android.gm.action.AUTO_SEND typ=text/plain cmp=com.google.android.gm/.AutoSendActivity (has extras)} from pid 8675 
02-20 14:05:05.821: I/AbstractCardView.SelfNoteCard(8675): #onViewDetachedFromWindow 

Esto me hace belive que Google dispone la audioFocus de Google Now (el regonizerIntent), y que se utilice un archivo de audio grabadora o algo similar cuando la etiqueta Note-to-self-tag aparece en onPartialResults. No puedo confirmar esto, ¿alguien más hizo intentos para que esto funcione?

0

Tengo un servicio que está implementando RecognitionListener y también anulo en el métodoBuferRecibido (byte []). Estaba investigando por qué el reconocimiento de voz es mucho más lento para llamar a Resultados() en < = ICS. La única diferencia que pude encontrar fue que onBufferReceived se llama en los teléfonos < = ICS. En JellyBean el onBufferReceived() nunca se llama y onResults() se llama significativamente más rápido y creo que es debido a la sobrecarga de llamar aBuferReceived cada segundo o milisegundo. Quizás es por eso que eliminaron onBufferReceived()?

Cuestiones relacionadas