¿Hay alguna manera de utilizar la API de SpeechRecognizer directamente para la entrada de voz?

El sitio web de Android Dev proporciona un ejemplo de cómo hacer una entrada de voz utilizando la actividad incorporada de Google Speech Input. La actividad muestra un pop-up preconfigurado con el micrófono y pasa sus resultados usando onActivityResult()

Mi pregunta: ¿hay alguna manera de usar la clase SpeechRecognizer directamente para hacer una entrada de voz sin mostrar la actividad enlatada? Esto me permitiría construir mi propia actividad para la entrada de voz.

Aquí está el código que usa la clase SpeechRecognizer (de aquí y aquí ):

 import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.speech.RecognitionListener; import android.speech.RecognizerIntent; import android.speech.SpeechRecognizer; import android.widget.Button; import android.widget.TextView; import java.util.ArrayList; import android.util.Log; public class VoiceRecognitionTest extends Activity implements OnClickListener { private TextView mText; private SpeechRecognizer sr; private static final String TAG = "MyStt3Activity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button speakButton = (Button) findViewById(R.id.btn_speak); mText = (TextView) findViewById(R.id.textView1); speakButton.setOnClickListener(this); sr = SpeechRecognizer.createSpeechRecognizer(this); sr.setRecognitionListener(new listener()); } class listener implements RecognitionListener { public void onReadyForSpeech(Bundle params) { Log.d(TAG, "onReadyForSpeech"); } public void onBeginningOfSpeech() { Log.d(TAG, "onBeginningOfSpeech"); } public void onRmsChanged(float rmsdB) { Log.d(TAG, "onRmsChanged"); } public void onBufferReceived(byte[] buffer) { Log.d(TAG, "onBufferReceived"); } public void onEndOfSpeech() { Log.d(TAG, "onEndofSpeech"); } public void onError(int error) { Log.d(TAG, "error " + error); mText.setText("error " + error); } public void onResults(Bundle results) { String str = new String(); Log.d(TAG, "onResults " + results); ArrayList data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); for (int i = 0; i < data.size(); i++) { Log.d(TAG, "result " + data.get(i)); str += data.get(i); } mText.setText("results: "+String.valueOf(data.size())); } public void onPartialResults(Bundle partialResults) { Log.d(TAG, "onPartialResults"); } public void onEvent(int eventType, Bundle params) { Log.d(TAG, "onEvent " + eventType); } } public void onClick(View v) { if (v.getId() == R.id.btn_speak) { 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,"voice.recognition.test"); intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,5); sr.startListening(intent); Log.i("111111","11111111"); } } } 

Defina main.xml con un botón y otorgue el permiso RECORD_AUDIO en manifiesto

También asegúrese de solicitar los permisos apropiados del usuario. Me quedé atrapado con un valor de retorno de error 9: INSUFFICIENT_PERMISSIONS, aunque tenía los permisos apropiados RECORD_AUDIO enumerados en el manifiesto.

Al seguir el código de muestra aquí , pude obtener los permisos del usuario y luego el reconocedor de voz arrojó buenas respuestas.

Por ejemplo, este bloque puse en mi onCreate () para la actividad, aunque podría ir a otro lugar en el flujo de UI, antes de llamar a los métodos de SpeechRecognizer:

  protected void onCreate(Bundle savedInstanceState) { ... if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) { // Show an explanation to the user *asynchronously* -- don't block // this thread waiting for the user's response! After the user // sees the explanation, try again to request the permission. } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 527); // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an // app-defined int constant. The callback method gets the // result of the request. (In this example I just punched in // the value 527) } ... } 

A continuación, proporcione un método de callback en la actividad para la solicitud de permisos:

 @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case 527: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // contacts-related task you need to do. } else { // permission denied, boo! Disable the // functionality that depends on this permission. } return; } // other 'case' lines to check for other // permissions this app might request } } 

Otra cosa que tengo que cambiar en el código de ejemplo anterior de preetha donde se recupera el texto resultante en el método onResults (). Para obtener el texto real de la voz traducida (en lugar del tamaño, como se imprime el código original), o bien imprima el valor de str de cadena construida u obtenga uno de los valores de retorno en ArrayList (datos). Por ejemplo:

 .setText(data.get(0)); 

Puede usar SpeechRecognizer , aunque no conozco ningún código de muestra más allá de esta pregunta SO anterior . Sin embargo, eso es nuevo en el nivel 8 de la API (Android 2.2) y, por lo tanto, no es ampliamente utilizable en el momento de escribir esto.