J'ai posé une question similaire à celle-ci plus tôt cette semaine mais je ne comprends toujours pas comment obtenir une liste de toutes les applications installées, puis en choisir une à exécuter.
J'ai essayé:
Intent intent = new Intent(ACTION_MAIN);
intent.addCategory(CATEGORY_LAUNCHER);
et cela ne montre que les applications préinstallées ou pouvant exécuter le type d'intention ACTION_MAIN.
Je sais aussi que je peux utiliser PackageManager pour obtenir toutes les applications installées, mais comment l'utiliser pour exécuter une application spécifique?
Voici le code pour obtenir la liste des activités/applications installées sur Android:
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> pkgAppsList = context.getPackageManager().queryIntentActivities( mainIntent, 0);
Vous obtiendrez toutes les données nécessaires dans la ResolveInfo
pour démarrer une application. Vous pouvez vérifier ResolveInfo
javadoc ici .
Voici une méthode plus propre en utilisant le 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()
Plus d'infos ici http://qtcstation.com/2011/02/how-to-launch-another-app-from-your-app/
Un autre moyen de filtrer les applications système (fonctionne avec l'exemple ci-dessus):
/**
* Return whether the given PackgeInfo 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);
}
Voici un bon exemple:
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;
}
Obtenir la liste des applications non-système installées
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);
}
}
}
Pour filtrer sur les applications basées sur le système:
private boolean isSystemPackage(ResolveInfo ri) {
return (ri.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
Pour obtenir toutes les applications installées, vous pouvez utiliser Package Manager.
List<PackageInfo> apps = getPackageManager().getInstalledPackages(0);
Pour exécuter, vous pouvez utiliser le nom du package
Intent launchApp = getPackageManager().getLaunchIntentForPackage(“package name”)
startActivity(launchApp);
Pour plus de détails, vous pouvez lire ce blog http://codebucket.co.in/Android-get-list-of-all-installed-apps/
Vous pouvez rechercher la liste des applications installées sur un périphérique Android à l'aide du code ci-dessous, "packageInfo" contient les informations sur les applications installéesin. nous pouvons suivre l’intention pour l’application installée à partir de l’objet packageinfo et en utilisant startactivity (intention), afin de démarrer l’application C'est à vous de décider comment organiser l'interface utilisateur, soit Listview ou Gridview. afin de cliquer sur un événement en fonction de votre position, vous pouvez rentrer l'intention object et démarrer l'activité.
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++;
}
}
S'il y a plusieurs lanceurs dans un même paquet, le code ci-dessus pose un problème. Exemple: sur LG, Optimus Facebook pour LG, MySpace pour LG, Twitter pour LG contient un nom de package SNS et si vous utilisez ci-dessus, SNS se répète. Après des heures de recherche, je suis arrivé avec le code ci-dessous. Semble bien travailler.
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;
}
@Jas: Je n'ai plus ce code, mais j'ai trouvé quelque chose de proche. J'ai fait ceci pour rechercher des "composants" de mon application, ce ne sont que des activités d'une catégorie donnée.
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;
}
J'ai commenté la partie où se trouve le nom de l'activité, mais c'est assez simple.
J'avais l'obligation de filtrer les applications système que les utilisateurs n'utilisaient pas vraiment (par exemple, "com.qualcomm.service", "update services", etc.). Finalement, j'ai ajouté une autre condition pour filtrer la liste des applications. Je viens de vérifier si l'application a «l'intention du lanceur».
Donc, le code résultant ressemble à ...
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);
}
}
L'idée derrière cette solution est que l'activité principale de chaque application système n'a pas de icône d'activité personnalisée. Cette méthode me donne un excellent résultat:
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;
}
Obtenez toutes les applications:
PackageManager pm = getContext().getPackageManager();
List<ApplicationInfo> apps = pm.getInstalledApplications(0);
Vérifiez si l'application est installée puis ouvrez:
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);
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;
}
}
J'ai une autre solution:
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;
}
vous pouvez utiliser ceci:
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
}
}
public static List<ApplicationInfo> getApplications(Context context) {
return context.getPackageManager().getInstalledApplications(PackageManager.GET_META_DATA);
}