utilizado sirve que para google developers android android-activity android-package-managers

sirve - se ha utilizado com google android packageinstaller



Android: cómo obtener una lista de actividades instaladas, tal como aparecen en el iniciador, sin duplicados (5)

Estoy escribiendo una aplicación que permite al usuario ver la lista de aplicaciones instaladas, seleccionar una de ellas y luego iniciarla según lo programado. Utilizando tutoriales de stackoverflow logré averiguar cómo obtener una lista de actividades instaladas, sus nombres e íconos de paquete (es decir, here , varias formas de hacerlo). Por las dudas, así es como comienzo las actividades, funciona a la perfección, 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 recuperar 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 de cada elemento de las apps puede obtener su nombre de paquete y 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 pueden no contener ninguna actividad y, por lo tanto, no se pueden iniciar. Aquí hay una captura de pantalla con un ejemplo:

Todos los elementos anteriores que no tienen iconos no se pueden abrir.

También hay un problema con el segundo enfoque: varios elementos de la lista tienen 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, porque me da una lista que es más adecuada para mis necesidades, pero no puedo encontrar una manera de filtrar los duplicados y solo mostrar la actividad predeterminada para la aplicación, tal como aparecen en el Iniciador (solo ve un ''Mapas'' en la lista de aplicaciones de su teléfono, no cuatro). Intenté filtrar las aplicaciones del sistema a través de ApplicationInfo.FLAG_SYSTEM , pero esto elimina muchas aplicaciones que quiero tener, incluidos Maps y otras aplicaciones preinstaladas. Intenté usar el indicador PackageManager.MATCH_DEFAULT_ONLY al ejecutar queryIntentActivities, pero esto también filtra muchas aplicaciones, dejando solo algunas.

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


Prueba el código a continuación y avísame qué pasó.

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 }


Puede que llegue tarde, pero acabo de encontrar una forma perfecta de que todas las aplicaciones tengan iniciador y no haya aplicaciones duplicadas (incluidas las aplicaciones del sistema, como contactos, mapas, etc.). Aunque, la respuesta de Satheesh podría estar funcionando (no me he controlado), pero quería elegir varias actividades, así que usé el código siguiente para instalar las aplicaciones.

Usé su segundo enfoque y descarté 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));


Tanto @Ashish Tanna como Jozze tienen razón, pero el rendimiento puede ser 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) Agregar un HashSet (2) Juzgar si la aplicación está habilitada (3) Juzgar si tiene dentro del hashset


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 iniciador".

Entonces, 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); } }


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);

Prueba este código Enumerará solo las aplicaciones que están todas instaladas en su dispositivo.