Android: Cómo obtener una lista de las actividades instaladas, tal y como aparecen en el lanzador, sin duplicados

Estoy escribiendo una aplicación que permite al usuario ver la lista de aplicaciones instaladas, seleccionar una de ellas y luego iniciarla de acuerdo con el calendario. Uso de tutoriales de stackoverflow i logrado averiguar cómo obtener una lista de las actividades instaladas, sus nombres de paquetes e iconos (es decir, aquí – varias maneras de hacerlo). Por si acaso, así es como empiezo las actividades, funciona perfectamente, no hay problema aquí:

Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName); launchIntent.setAction(Intent.ACTION_MAIN); launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(launchIntent); 

El problema es con la recuperación de una lista de aplicaciones instaladas. He encontrado dos formas de obtener una lista de aplicaciones instaladas:

1) uso

 PackageManager pm = getPackageManager(); List<ApplicationInfo> apps = pm.getInstalledApplication(PackageManager.GET_META_DATA) 

Y desde cada elemento de las apps se puede obtener su nombre del paquete y la etiqueta del paquete (nombres de la aplicación).

2) uso

 PackageManager pm = getPackageManager(); Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(mainIntent, 0); for(ResolveInfo info : resolveInfos) { ApplicationInfo applicationInfo = info.activityInfo.applicationInfo; //... //get package name, icon and label from applicationInfo object } 

Hay un problema con el primer método: devuelve todos los paquetes instalados, incluidos los servicios del sistema, que no pueden contener ninguna actividad y, por lo tanto, no se pueden iniciar. Aquí hay una captura de pantalla con un ejemplo: Lista de aplicaciones con paquetes

Todos los elementos anteriores que no tienen iconos no pueden iniciarse.

Hay un problema con el segundo enfoque también: Varios elementos de la lista tienen duplicados: Lista de aplicaciones con duplicados

Cuando configuro un punto de interrupción en el depurador, veo que estos elementos de "Mapas" tienen diferentes nombres de actividad ("com.google.android.maps.MapsActivity", "com.google.android.maps.LatitudeActivity", "com.google .android.maps.PlacesActivity "etc.).

Decidí usar el segundo enfoque, ya que da una lista que es más adecuada para mis necesidades, pero no puedo encontrar una manera de filtrar los duplicados y mostrar sólo la actividad predeterminada para la aplicación, ya que aparecen en el Lanzador (Solo ves un 'Mapas' en la lista de aplicaciones de tu teléfono, no cuatro). He intentado filtrar las aplicaciones del sistema a través de ApplicationInfo.FLAG_SYSTEM , pero esto elimina muchas aplicaciones que quiero tener, incluyendo Mapas y otras aplicaciones preinstaladas. He intentado usar el indicador PackageManager.MATCH_DEFAULT_ONLY al ejecutar queryIntentActivities, pero esto también filtra muchas aplicaciones, dejando sólo algunas.

Estoy un poco perdido aquí, y no sé qué hacer. He leído todas las preguntas sobre stackoverflow sobre la recuperación de una lista de aplicaciones instaladas, pero este problema nunca ha surgido. Por favor, ayuda a alguien? ¿Cómo recupero una lista de aplicaciones iniciales instaladas que no tiene duplicados?

 Intent localIntent2 = new Intent("android.intent.action.PICK_ACTIVITY"); Intent localIntent3 = new Intent("android.intent.action.MAIN",null); localIntent3.addCategory("android.intent.category.LAUNCHER"); localIntent2.putExtra("android.intent.extra.INTENT",localIntent3); startActivityForResult(localIntent2, 1); 

Pruebe este código. Sólo mostrará las aplicaciones que están instaladas en su dispositivo.

Puedo llegar tarde, pero acabo de encontrar una manera perfecta de obtener todas las aplicaciones que tengan lanzador y no aplicaciones duplicadas (incluyendo aplicaciones del sistema como contactos, mapas, etc.). Aunque, la respuesta de Satheesh podría estar funcionando (no me he comprobado), pero quería elegir varias actividades, así que usé código debajo para instalar las aplicaciones.

Utilicé su segundo enfoque y descarté los paquetes duplicados usando HashSet. Aquí está el código final:

  final PackageManager packageManager = getPackageManager(); Intent intent = new Intent(Intent.ACTION_MAIN, null); intent.addCategory(Intent.CATEGORY_LAUNCHER); List<ResolveInfo> resInfos = packageManager.queryIntentActivities(intent, 0); //using hashset so that there will be no duplicate packages, //if no duplicate packages then there will be no duplicate apps HashSet<String> packageNames = new HashSet<String>(0); List<ApplicationInfo> appInfos = new ArrayList<ApplicationInfo>(0); //getting package names and adding them to the hashset for(ResolveInfo resolveInfo : resInfos) { packageNames.add(resolveInfo.activityInfo.packageName); } //now we have unique packages in the hashset, so get their application infos //and add them to the arraylist for(String packageName : packageNames) { try { appInfos.add(packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)); } catch (NameNotFoundException e) { //Do Nothing } } //to sort the list of apps by their names Collections.sort(appInfos, new ApplicationInfo.DisplayNameComparator(packageManager)); 

Intente abajo el código y déjeme saben lo que sucedió.

 PackageManager manager = getPackageManager(); Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); List<ResolveInfo> resolveInfos= manager.queryIntentActivities(mainIntent, 0); // Below line is new code i added to your code Collections.sort(resolveInfos, new ResolveInfo.DisplayNameComparator(manager)); for(ResolveInfo info : resolveInfos) { ApplicationInfo applicationInfo = info.activityInfo.applicationInfo; //... //get package name, icon and label from applicationInfo object } 

Yo tenía el mismo requisito. Finalmente, agregué otra condición para filtrar la lista de aplicaciones. Acabo de comprobar si la aplicación tiene 'intención de lanzador'.

Así, el código resultante parece …

 PackageManager pm = getPackageManager(); List<ApplicationInfo> apps = pm.getInstalledApplications(PackageManager.GET_GIDS); for (ApplicationInfo app : apps) { if(pm.getLaunchIntentForPackage(app.packageName) != null) { // apps with launcher intent if((app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1) { // updated system apps } else if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 1) { // system apps } else { // user installed apps } appsList.add(app); } } 

Ambos @Ashish Tanna y jozze tienen razón, pero el rendimiento tal vez un pequeño problema.

Este es el mejor rendimiento.

 Set<String> packageNameSet = new HashSet<>(); PackageManager pm = context.getPackageManager(); Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(mainIntent, 0); for(ResolveInfo info : resolveInfos) { // be added ApplicationInfo applicationInfo; if (info == null || (applicationInfo = info.activityInfo.applicationInfo) == null || !applicationInfo.enabled || packageNameSet.contains(applicationInfo.packageName)) { continue; } packageNameSet.add(applicationInfo.packageName); //... //get package name, icon and label from applicationInfo object } 

(1) Añadir un HashSet (2) Juzgar si la aplicación está habilitada (3) Juzgar si tiene dentro del hashset

  • ¿Qué significa esto: Fallo ?
  • Manera de obtener el nombre de etiqueta localizado de PackageManager
  • Comportamiento impredecible causado por PackageManager.DONT_KILL_APP
  • Obtener iconos de todas las aplicaciones instaladas en android
  • Resolver "Administrador de paquetes ha muerto" RuntimeException
  • Método de reflexión de Android M freeStorageAndNotify excepción
  • Diferencia entre el comando "install" de adb y el comando "pm install"?
  • Obtener el nombre de la aplicación activa en Android
  • Obtener todas las actividades mediante el uso del nombre del paquete
  • Cómo detectar nuevas aplicaciones en un dispositivo Android
  • Cómo comprobar si la instalación es de la tienda de aplicaciones de Samsung
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.