Widget que llama a la aplicación de reconocimiento de voz

Estoy tratando de crear un widget que contiene un solo ImageView que, al hacer clic, inicia la aplicación de reconocimiento de voz. Nunca he trabajado con widgets e intentos pendientes, así que estoy confundido: ¿cómo crear una intención pendiente para iniciar la actividad de reconocimiento de voz?

He intentado con algo como esto, pero, por supuesto, falla:

    Intención intención = nueva Intención ();
    Intención voiceIntent = new Intent (RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    VoiceIntent.putExtra (RecognizerIntent.EXTRA_LANGUAGE_MODEL,
      RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    VoiceIntent.putExtra (RecognizerIntent.EXTRA_PROMPT,
      "Demo de reconocimiento de voz");
    VoiceIntent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
    Intent.putExtra (RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, voiceIntent);
    PendingIntent pendingIntent = PendingIntent.getActivity (contexto, 0,
      Intención, 0);
    RemoteViews views = new RemoteViews (context.getPackageName (),
      R.layout.main);
    Views.setOnClickPendingIntent (R.id.button, pendingIntent);

¡Entiendo! Necesitaba dos intentos regulares envueltos en dos intentos pendientes, como esto:

// this intent points to activity that should handle results Intent activityIntent = new Intent(context, ResultsActivity.class); // this intent wraps results activity intent PendingIntent resultsPendingIntent = PendingIntent.getActivity(context, 0, activityIntent, 0); // this intent calls the speech recognition Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speech recognition demo"); voiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, resultsPendingIntent); // this intent wraps voice recognition intent PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, voiceIntent, 0); rv.setOnClickPendingIntent(R.id.btn, pendingIntent); 

Me encuentro con el mismo problema, también.
Siento que no tengo suficiente reputación para comentar.

No es necesario usar una actividad transparente para enviar una intención de reconocimiento.
Como la respuesta de zorglub76

 Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speech recognition demo"); voiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, resultsPendingIntent); 

El resultado del reconocimiento sólo será en el extra de la resultingPendingIntent
Así que todo lo que necesitas hacer es:

En ResultsActivity.onCreate()

 ArrayList<String> voiceResults = this.getIntent().getExtras().getStringArrayList(RecognizerIntent.EXTRA_RESULTS); 

Cuidado de la NullPointerException , y obtendrá el resultado de la ArrayList !!

Quería crear google como widget. He intentado zorglub76 solución, pero no pude conseguir la voz el resultado …

Lo solucioné creando una actividad simulada transparente que maneja el reconocimiento de voz de extremo a extremo.

Funciona de la siguiente manera: Widget-> VoiceRecognitionStarterActivity-> RecognizerIntent-> VoiceRecognitionStarterActivity.onActivityResult.

Mi clase de widget:

 public class MyWidgetProvider extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) { // Get all ids ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class); int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); for (int widgetId : allWidgetIds) { RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout); Intent activityIntent = new Intent(context, VoiceRecognitionStarterActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, activityIntent, 0); remoteViews.setOnClickPendingIntent(R.id.mic_image, pendingIntent); activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(context.getString(R.string.search_url))); pendingIntent = PendingIntent.getActivity(context, 0, activityIntent, 0); remoteViews.setOnClickPendingIntent(R.id.search_box_image, pendingIntent); appWidgetManager.updateAppWidget(widgetId, remoteViews); } } } 

Mi actividad transparrent:

  public class VoiceRecognitionStarterActivity extends Activity { private static final String TAG = "VoiceRecognitionStarterActivity"; private int SPEECH_REQUEST_CODE = 1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sendRecognizeIntent(); } private void sendRecognizeIntent() { Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speak to search"); intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 10); startActivityForResult(intent, SPEECH_REQUEST_CODE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == SPEECH_REQUEST_CODE) { if (resultCode == RESULT_OK) { Log.d(TAG, "result ok"); Intent searchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.search_url))); startActivity(searchIntent); finish(); } else { Log.d(TAG, "result NOT ok"); finish(); } } super.onActivityResult(requestCode, resultCode, data); } } 

Para hacer transparente la actividad, vea esta publicación

Esto es totalmente funcional y se basa en el widget ListView en el SDK de Android. No es particularmente para un widget, pero estoy seguro de que puede modificarlo para que funcione para un widget.

Cree una actividad llamada SearchActivity:

 // CustomSearch (View) & ISearch (Interface) are objects that I created and are irrelevant public class SearchActivity extends AppCompatActivity implements ISearch { // Variables private CustomSearch mSearchView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_search); mSearchView = (CustomSearch)findViewById(R.id.search); mSearchView.setPendingComponentName(getComponentName()); mSearchView.setSearchListener(this); } @Override protected void onNewIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); Log.i("SEARCH >", "You said: " + query); } } } 

Añadir actividad a AndroidManifest.xml

 <activity android:name=".activities.SearchActivity" android:label="@string/app_name" android:theme="@style/CustomTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.SEARCH"/> </intent-filter> </activity> 

En tu Widget personalizado / Ver:

 buttonVoice.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Get activity from either SearchableInfo or ComponentName ComponentName searchActivity = mComponentName; // Wrap component in intent Intent queryIntent = new Intent(Intent.ACTION_SEARCH); queryIntent.setComponent(searchActivity); // Wrap query intent in pending intent PendingIntent pending = PendingIntent.getActivity(getContext(), 0, queryIntent, PendingIntent.FLAG_ONE_SHOT); // Create bundle now because if we wrap it in pending intent, it becomes immutable Bundle queryExtras = new Bundle(); // Create voice intent Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZER_SPEECH); voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.ACTION_RECOGNIZE_SPEECH); voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speak"); voiceIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, searchActivity voiceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Wrap the pending intent & bundle inside the voice intent voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, pending); voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT_BUNDLE, queryExtras); // Start the voice search getContext().startActivity(voiceIntent); } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.