2011-09-30 9 views
5

Tengo una pregunta acerca de la resolución de intención y la diferencia entre Intent.ACTION_PICK_ACTIVITY e Intent.ACTION_CHOOSER (incluida su función de función de conveniencia, Intent.createChooser()).Resolución de intenciones y diferencia entre ACTION_CHOOSER y ACTION_PICK_ACTIVITY

Estoy escribiendo una aplicación "administrador de paquetes". En él tengo una ListActivity que muestra todos los paquetes instalados en el dispositivo (rellenado con PackageManager.getInstalledPackages()). También tengo un menú contextual registrado en la lista, uno de cuyos ítems es "Iniciar".

A continuación se muestra mi código de onContextItemSelected() para manejar el elemento de menú contextual "Iniciar".

Intent intent ; 
List<ResolveInfo> ris ; 
int nLauchables ; 
int REQUEST_LAUNCH = 1 ; // for use in onActivityResult() 
// PackageInfo pi ;   // set outside this code 

intent = new Intent (Intent.ACTION_MAIN) ; 
intent.addCategory (Intent.CATEGORY_LAUNCHER) ; 
intent.setPackage (pi.packageName) ; // limit to launchable activities in the package represented by pi 

ris = getPackageManager().queryIntentActivities (intent, 0) ; // get list of launchable activities in pi 
nLaunchables = ris.size() ; 

if (ris == null || nLaunchables == 0) { 
// do nothing (in the real code, the "Launch" item is already disabled in this case, so this never happens) 
    } 
else if (nLaunchables == 1) { 
// only 1 launchable activity, so just start that activity 

    intent.setComponent (new ComponentName (ris.get (0).activityInfo.packageName, ris.get (0).activityInfo.name)) ; 

    startActivity (intent) ; 
    } 
else if (nLaunchables > 1) { 
// mutiple launchable activites, so let the user choose which one they want to launch 

// Intent chooseIntent = new Intent (Intent.ACTION_CHOOSER) ; 
// chooseIntent.putExtra (Intent.EXTRA_INTENT, intent) ; 
// chooseIntent.putExtra (Intent.EXTRA_TITLE, "Select activity") ; 
// startActivity (chooseIntent) ;          // doesn't show all launchable activities in the package 
// 
// or 
// 
// startActivity (Intent.createChooser (intent, "Select activity") ; // doesn't show all launchable activities in the package 

    Intent pickIntent = new Intent (Intent.ACTION_PICK_ACTIVITY) ; 
    pickIntent.putExtra (Intent.EXTRA_INTENT, intent) ; 

    startActivityForResult (pickIntent, REQUEST_LAUNCH) ; 
    } 

me trataron primero la versión ACTION_CHOOSER ... pero no siempre muestra todas las actividades lanzables en el paquete. Por ejemplo, Google Maps tiene 4 actividades de lanzamiento (Latitude, Maps, Navigation y Places) que aparecen con ACTION_PICK_ACTIVITY pero ACTION_CHOOSER solo muestra 2 (Latitude, Maps). Lo único que puedo ver que es diferente entre las actividades que se muestran al usar ACTION_CHOOSER y las que no lo hacen es que tienen CATEGORY_DEFAULT en su < filtro de intención> s.

A continuación se presentan las partes de la documentación que he consultado para entender lo que está pasando:

Docs for CATEGORY_DEFAULT decir, en parte, "Configuración Esto ocultará al usuario cualquier actividad sin que establecen cuando se realiza una acción en algunos datos."

Esto parece explicar el comportamiento que estoy viendo ... pero ...

Docs for ACTION_CHOOSER decir, en parte," ... todas las actividades posibles siempre se le aparecen incluso si uno de ellos están marcados actualmente como la actividad preferida ". (énfasis mío)

Esto parece estar en conflicto con los documentos anteriores para CATEGORY_DEFAULT y sugiere que el uso de ACTION_CHOOSER y ACTION_PICK_ACTIVITY debe producir los mismos resultados. ... y ...

Documentos para Intents y Resolución de Intención (lo siento, como un nuevo usuario, estoy limitado a 2 enlaces en una publicación, por lo que no puedo vincular a esto ... solo mire en la sección "Resolución de Intención", subsección "Prueba de Categoría", dice, en parte, "Android trata todos los intentos implícitos pasados ​​a startActivity() como si contuvieran al menos una categoría: android.intent.category.DEFAULT" (the CATEGORY_DEFAULT constante). Por lo tanto, las actividades que están dispuestas a recibir intentos implícitos deben incluir android.intent.category.DEFAULT "en sus filtros de intención. (Filtros con android.intent.action.MAIN" y android.intent.category.LAUNCHER "la configuración es la excepción. Marcan actividades que comienzan nuevas tareas y que están representadas en la pantalla del iniciador. Pueden incluir "android.intent.category.DEFAULT" en la lista de categorías, pero no es necesario.) "(énfasis mío)

Nuevamente, esto parece indicar explícitamente que usar ACTION_CHOOSER y ACTION_PICK_ACTIVITY debería producir los mismos resultados.

Entonces, ¿se trata solo de una documentación incompleta para ACTION_CHOOSER (es decir, que no menciona que las actividades de CATEGORY_DEFAULT están excluidas) o hay algo más que esté pasando?

El uso de ACTION_PICK_ACTIVITY funciona para mí, pero no es ideal debido a la necesidad de llamar a startActivityForResult() con él (en lugar de simplemente startActivity()).

Respuesta

0

Creo que su lectura de esos dos últimos pasajes de la documentación no es el significado previsto. Comenzando con el documento ACTION_CHOOSER, "... todas las actividades posibles se mostrarán siempre, aunque una de ellas esté marcada actualmente como la actividad preferida", se refiere específicamente a las actividades preferidas. Normalmente, cuando utilizas un intento implícito y coincide más de una actividad, si el usuario ha elegido previamente "Siempre" de un selector anterior para esta intención, entonces obtendrás esa actividad sin un selector. Si usa el intento ACTION_CHOOSER, obtendrá todas las actividades que coincidan, incluso si se ha elegido una. Eso es todo lo que significa esta línea: "todas las actividades posibles" se refiere a todas las actividades que coinciden con el filtro de intención, teniendo en cuenta también las categorías. Es simplemente otra explicación de la diferencia entre obtener un selector automáticamente y usar ACTION_CHOOSER.

La otra parte que usted llama, aproximadamente android.intent.action.MAIN y , no significa que esa acción y categoría se manejan especialmente en el proceso de filtrado de intención. No olvide que la mayoría de las personas que leen esta documentación simplemente escriben aplicaciones que se pueden lanzar, y necesitan saber qué poner en su manifiesto para obtener una actividad que se muestra en el iniciador. La "excepción" aquí no es una excepción a las reglas de filtro de intención: es una excepción al comportamiento habitual que los intentos implícitos usan CATEGORY_DEFAULT, y eso es solo una excepción porque los lanzadores establecen esta categoría (CATEGORY_LAUNCHER) en lugar de CATEGORY_DEFAULT.

En resumen, toda el área de la resolución de intención está bastante poco documentada, como ha encontrado, pero no hay inconsistencia en los extractos que ha mencionado: simplemente están hablando de cosas ligeramente diferentes.