Cómo obtener una lista de aplicaciones de Android instaladas y elegir una para ejecutar

326

Hice una pregunta similar a esta a principios de esta semana, pero todavía no entiendo cómo obtener una lista de todas las aplicaciones instaladas y luego elegir una para ejecutarla.

He intentado:

Intent intent = new Intent(ACTION_MAIN);
intent.addCategory(CATEGORY_LAUNCHER);

y esto solo muestra aplicaciones preinstaladas o que pueden ejecutar el ACTION_MAINtipo Intent.

También sé que puedo usar PackageManagerpara obtener todas las aplicaciones instaladas, pero ¿cómo puedo usar esto para ejecutar una aplicación específica?

2Real
fuente
¿Cómo solo puede obtener la información sobre la aplicación seleccionada en la lista?
Pedrum

Respuestas:

277

El siguiente es el código para obtener la lista de actividades / aplicaciones instaladas en Android:

Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> pkgAppsList = context.getPackageManager().queryIntentActivities( mainIntent, 0);

Obtendrá todos los datos necesarios ResolveInfopara iniciar una aplicación. Puedes consultar ResolveInfojavadoc aquí .

Karan
fuente
3
¿Cómo puedo comenzar uno de estos? Obtuve la actividadInfo dentro de ResolveInfo, pero no puedo iniciarlo.
Spidey
1
No importa, lo encontré. Debería crear una nueva intención utilizando el nombre completo de la clase (paquete + clase).
Spidey
¿Cómo solo puede obtener la información sobre la aplicación seleccionada en la lista?
Pedrum
1
Quería comprender la política de Android / Play Store sobre la lectura y el almacenamiento de mi aplicación, una lista de todas las aplicaciones y la posibilidad de comunicarme con un servidor. ¿Hay alguna guía?
dowjones123
1
@ dowjones123 ¿Encontraste las pautas sobre esto?
RmK
415

Aquí hay una forma más limpia de usar PackageManager

final PackageManager pm = getPackageManager();
//get a list of installed apps.
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);

for (ApplicationInfo packageInfo : packages) {
    Log.d(TAG, "Installed package :" + packageInfo.packageName);
    Log.d(TAG, "Source dir : " + packageInfo.sourceDir);
    Log.d(TAG, "Launch Activity :" + pm.getLaunchIntentForPackage(packageInfo.packageName)); 
}
// the getLaunchIntentForPackage returns an intent that you can use with startActivity() 

Más información aquí http://qtcstation.com/2011/02/how-to-launch-another-app-from-your-app/

Nelson Ramirez
fuente
Funciona gr8. Pero cuando probé esto en Android 4.0.3, ¡nada se imprime! Cualquier pista ??
Saurabh Verma
Asegúrese de no filtrar las declaraciones del registro de depuración.
QED
Este código funciona, sin embargo, ¿tiene alguna idea sobre cómo poner esa lista de aplicaciones en un ListView?
androidBoomer
@androidBoomer estoy haciendo lo mismo. lea esto aquí - vogella.com/tutorials/AndroidListView/article.html
David T.
@DavidT. Ya lo descubrí. Ahora, estoy trabajando en cómo puedo acceder a esas aplicaciones instaladas para crear un acceso directo dentro de mi aplicación. ¿Es eso posible?
androidBoomer
61

Otra forma de filtrar las aplicaciones del sistema (funciona con el ejemplo de king9981):

/**
 * Return whether the given PackageInfo represents a system package or not.
 * User-installed packages (Market or otherwise) should not be denoted as
 * system packages.
 * 
 * @param pkgInfo
 * @return
 */
private boolean isSystemPackage(PackageInfo pkgInfo) {
    return ((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
}
Kenneth Evans
fuente
44
Esta es la mejor respuesta para filtrar aplicaciones del sistema.
Bjorn
55
Pero no filtra la aplicación como la configuración, los mapas o ..., cómo enumerarlos también
Ata
77
La parte "? Verdadero: falso" de su declaración de devolución es redundante
k2col
simplificar return ((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)! = 0);
Bhavesh Rangani
¿Cómo filtrar aplicaciones pagas?
Pemba Tamang
55

Aquí un buen ejemplo:

class PInfo {
    private String appname = "";
    private String pname = "";
    private String versionName = "";
    private int versionCode = 0;
    private Drawable icon;
    private void prettyPrint() {
        Log.v(appname + "\t" + pname + "\t" + versionName + "\t" + versionCode);
    }
}

private ArrayList<PInfo> getPackages() {
    ArrayList<PInfo> apps = getInstalledApps(false); /* false = no system packages */
    final int max = apps.size();
    for (int i=0; i<max; i++) {
        apps.get(i).prettyPrint();
    }
    return apps;
}

private ArrayList<PInfo> getInstalledApps(boolean getSysPackages) {
    ArrayList<PInfo> res = new ArrayList<PInfo>();        
    List<PackageInfo> packs = getPackageManager().getInstalledPackages(0);
    for(int i=0;i<packs.size();i++) {
        PackageInfo p = packs.get(i);
        if ((!getSysPackages) && (p.versionName == null)) {
            continue ;
        }
        PInfo newInfo = new PInfo();
        newInfo.appname = p.applicationInfo.loadLabel(getPackageManager()).toString();
        newInfo.pname = p.packageName;
        newInfo.versionName = p.versionName;
        newInfo.versionCode = p.versionCode;
        newInfo.icon = p.applicationInfo.loadIcon(getPackageManager());
        res.add(newInfo);
    }
    return res; 
}
king9981
fuente
1
¿Cómo ejecutas uno de esos si es necesario? Quiero decir, ¿puedes obtener la intención?
Ton
Excelente. Gracias por tu respuesta. He usado su respuesta en mi solicitud y tengo un pequeño problema con el tamaño del icono. la mayoría de ellos son normales y algunos son muy grandes o pequeños. Cómo puedo arreglar eso. ¿Tiene usted alguna idea? gracias
Meysam Valueian
37

Obtener una lista de aplicaciones instaladas que no son del sistema

public static void installedApps()
{
    List<PackageInfo> packList = getPackageManager().getInstalledPackages(0);
    for (int i=0; i < packList.size(); i++)
    {
        PackageInfo packInfo = packList.get(i);
        if (  (packInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)
        {
            String appName = packInfo.applicationInfo.loadLabel(getPackageManager()).toString();
            Log.e("App № " + Integer.toString(i), appName);
        }
    }
}
XXX
fuente
19

Para filtrar en aplicaciones basadas en sistemas:

private boolean isSystemPackage(ResolveInfo ri) {
    return (ri.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
SamCsharpAs3
fuente
18

Para obtener todas las aplicaciones instaladas, puede usar Package Manager.

    List<PackageInfo> apps = getPackageManager().getInstalledPackages(0);

Para ejecutar puede usar el nombre del paquete

Intent launchApp = getPackageManager().getLaunchIntentForPackage(“package name”)
startActivity(launchApp);

Para obtener más detalles, puede leer este blog http://codebucket.co.in/android-get-list-of-all-installed-apps/

Arvind
fuente
Esto es más al punto. Podemos establecer una verificación adecuada descubriendo nuestra aplicación requerida.
Noman
13

Puede encontrar la lista de aplicaciones instaladas en el dispositivo Android utilizando el siguiente código, "packageInfo" contiene información de la aplicación instalada en el dispositivo. podemos recuperar Intent para la aplicación instalada desde el objeto packageinfo y, mediante el uso de startactivity (intent), podemos iniciar la aplicación. depende de usted cómo organizar la interfaz de usuario, ya sea Listview o Gridview. así que en el evento de clic basado en la posición, puede recuperar el objeto de intención e iniciar la intención de actividad.

final PackageManager pm = getPackageManager();

List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);


for (ApplicationInfo packageInfo : packages) 

{
 if(pm.getLaunchIntentForPackage(packageInfo.packageName)!= null &&   

                   !pm.getLaunchIntentForPackage(packageInfo.packageName).equals(""))


{

    System.out.println("Package Name :" + packageInfo.packageName);

    System.out.println("Launch Intent For Package :"   +  
                  pm.getLaunchIntentForPackage(packageInfo.packageName));

    System.out.println("Application Label :"   + pm.getApplicationLabel(packageInfo));

    System.out.println("Application Label :"   + 
                           pm.getApplicationIcon(packageInfo.packageName).toString());

    System.out.println("i : "+i);

    /*if(i==2)

    {
         startActivity(pm.getLaunchIntentForPackage(packageInfo.packageName));

     break;

    }*/

    i++;

}
}
Prashant Agrawal
fuente
13

Tenía el requisito de filtrar las aplicaciones del sistema que el usuario realmente no usa (por ejemplo, "com.qualcomm.service", "servicios de actualización", etc.). Finalmente, agregué otra condición para filtrar la lista de aplicaciones. Acabo de comprobar si la aplicación tiene 'intención de inicio'.

Entonces, el código resultante se parece a ...

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) != 0) {
                    // updated system apps

                } else if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                    // system apps

                } else {
                    // user installed apps

                }
                appsList.add(app);
            }

        }
joecizac
fuente
Gracias. GetLaunchIntentForPackage es muy útil para obtener las aplicaciones presentes en el cajón de aplicaciones :-)
Gabriel Hautclocq
10

Si hay múltiples lanzadores en un paquete, el código anterior tiene un problema. Por ejemplo: en LG Optimus, Facebook para LG, MySpace para LG, Twitter para LG contiene en un paquete el nombre de SNS y si lo usa arriba, SNS se repetirá. Después de horas de investigación, llegué con el siguiente código. Parece funcionar bien.

private List<String> getInstalledComponentList()
            throws NameNotFoundException {
        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        List<ResolveInfo> ril = getPackageManager().queryIntentActivities(mainIntent, 0);
        List<String> componentList = new ArrayList<String>();
        String name = null;

        for (ResolveInfo ri : ril) {
            if (ri.activityInfo != null) {
                Resources res = getPackageManager().getResourcesForApplication(ri.activityInfo.applicationInfo);
                if (ri.activityInfo.labelRes != 0) {
                    name = res.getString(ri.activityInfo.labelRes);
                } else {
                    name = ri.activityInfo.applicationInfo.loadLabel(
                            getPackageManager()).toString();
                }
                componentList.add(name);
            }
        }
        return componentList;
    }
kakopappa
fuente
7

@Jas: Ya no tengo ese código, pero he encontrado algo cercano. He hecho esto para buscar "componentes" de mi aplicación, son solo actividades con una categoría determinada.

private List<String> getInstalledComponentList() {
    Intent componentSearchIntent = new Intent();
    componentSearchIntent.addCategory(Constants.COMPONENTS_INTENT_CATEGORY);
    componentSearchIntent.setAction(Constants.COMPONENTS_INTENT_ACTION_DEFAULT);
    List<ResolveInfo> ril = getPackageManager().queryIntentActivities(componentSearchIntent, PackageManager.MATCH_DEFAULT_ONLY);
    List<String> componentList = new ArrayList<String>();
    Log.d(LOG_TAG, "Search for installed components found " + ril.size() + " matches.");
    for (ResolveInfo ri : ril) {
        if (ri.activityInfo != null) {
            componentList.add(ri.activityInfo.packageName);// + ri.activityInfo.name);
            Log.d(LOG_TAG, "Found installed: " + componentList.get(componentList.size()-1));
        }
    }
    return componentList;
}

He comentado la parte donde recibe el nombre de la actividad, pero es bastante sencillo.

Araña
fuente
6

Solución limpia que filtra con éxito las aplicaciones del sistema

La idea detrás de esta solución es que la actividad principal de cada aplicación del sistema no tiene un ícono de actividad personalizado . Este método me da un excelente resultado:

 public static Set<PackageInfo> getInstalledApps(Context ctx) {
    final PackageManager packageManager = ctx.getPackageManager();

    final List<PackageInfo> allInstalledPackages = packageManager.getInstalledPackages(PackageManager.GET_META_DATA);
    final Set<PackageInfo> filteredPackages = new HashSet();

    Drawable defaultActivityIcon = packageManager.getDefaultActivityIcon();

    for(PackageInfo each : allInstalledPackages) {
        if(ctx.getPackageName().equals(each.packageName)) {
            continue;  // skip own app
        }

        try {
            // add only apps with application icon
            Intent intentOfStartActivity = packageManager.getLaunchIntentForPackage(each.packageName);
            if(intentOfStartActivity == null)
                continue;

            Drawable applicationIcon = packageManager.getActivityIcon(intentOfStartActivity);
            if(applicationIcon != null && !defaultActivityIcon.equals(applicationIcon)) {
                filteredPackages.add(each);
            }
        } catch (PackageManager.NameNotFoundException e) {
            Log.i("MyTag", "Unknown package name " + each.packageName);
        }
    }

    return filteredPackages;
}
Funcoder
fuente
3
private static boolean isThisASystemPackage(Context context, PackageInfo  packageInfo ) {
        try {
            PackageInfo sys = context.getPackageManager().getPackageInfo("android", PackageManager.GET_SIGNATURES);
            return (packageInfo != null && packageInfo.signatures != null &&
                    sys.signatures[0].equals(packageInfo.signatures[0]));
        } catch (NameNotFoundException e) {
            return false;
        }
    }
usuario1546570
fuente
2

Tengo otra solucion:

ArrayList<AppInfo> myAppsToUpdate;

    // How to get the system and the user apps.
    public ArrayList<AppInfo> getAppsToUpdate() {

        PackageManager pm = App.getContext().getPackageManager();
        List<ApplicationInfo> installedApps = pm.getInstalledApplications(0);
        myAppsToUpdate = new ArrayList<AppInfo>();
        for (ApplicationInfo aInfo : installedApps) {

            if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                // System apps 
            } else {
                // Users apps
                AppInfo appInfo = new AppInfo();
                appInfo.setAppName(aInfo.loadLabel(pm).toString());
                appInfo.setPackageName(aInfo.packageName);
                appInfo.setLaunchActivity(pm.getLaunchIntentForPackage(aInfo.packageName).toString());
                try {
                    PackageInfo info = pm.getPackageInfo(aInfo.packageName, 0);
                    appInfo.setVersionName(info.versionName.toString());
                    appInfo.setVersionCode("" + info.versionCode);
                    myAppsToUpdate.add(appInfo);
                } catch (NameNotFoundException e) {
                    Log.e("ERROR", "we could not get the user's apps");
                }

            }
        }
        return myAppsToUpdate;
    }
Victor Ruiz.
fuente
2

Obtén todas las aplicaciones:

    PackageManager pm = getContext().getPackageManager();
    List<ApplicationInfo> apps = pm.getInstalledApplications(0);

Verifique si la aplicación instalada luego abre:

if((app.flags & (ApplicationInfo.FLAG_UPDATED_SYSTEM_APP | ApplicationInfo.FLAG_SYSTEM)) > 0) {
                String app_package = app.packageName;
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(app_package);
context.startActivity(launchIntent);
Chandra Agarwala
fuente
0

puedes usar esto:

PackageManager pm = getApplicationContext().getPackageManager();
                List<ResolveInfo> activityList = pm.queryIntentActivities(shareIntent, 0);
                for (final ResolveInfo app : activityList) 
                {
                   if ((app.activityInfo.name).contains("facebook")) 
                   {
                     // facebook  
                   }

                   if ((app.activityInfo.name).contains("android.gm")) 
                   {
                     // gmail  
                   }

                   if ((app.activityInfo.name).contains("mms")) 
                   {
                     // android messaging app
                   }

                   if ((app.activityInfo.name).contains("com.android.bluetooth")) 
                   {
                     // android bluetooth  
                   }
                }
Akshay Paliwal
fuente
0
public static List<ApplicationInfo> getApplications(Context context) {
    return context.getPackageManager().getInstalledApplications(PackageManager.GET_META_DATA);
}
Reza
fuente