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:
- ¿Es persistente PackageManager.getComponentEnabledSettings () entre arranques en frío?
- No se pueden obtener filtros de intenciones de un paquete
- Lista de aplicaciones predeterminadas que muestran errores en Android L
- Quitar actividad como iniciador predeterminado
- Desactivar las notificaciones de una aplicación mediante programación en Android
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:
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:
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?
- ¿Cómo visible / invisible icono del lanzador en android?
- Llamar al receptor de difusión al momento de desinstalar la aplicación en android
- Cómo cambiar el tema de otro recurso de la aplicación en android?
- Cómo averiguar si una llamada de Skype está actualmente activa en Android
- Android ClassCastException con el tipo en blanco
- Cambiar información de la aplicación de la aplicación del gestor de paquetes en android
- Obtener una aplicación preferida / predeterminada en Android
- Obtener minSdkVersion y targetSdkVersion del archivo apk
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
- Grabación de vídeo de la aplicación Android cuando la pantalla está desactivada
- "ComputeValuesWithHarfbuzz – necesidad de forzar a una sola ejecución" en Android 4: ¿Qué significa esto?