本周早些时候,我问了一个类似的问题,但我仍然不明白如何获得所有已安装的应用程序的列表,然后选择一个运行。

我试过了:

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

这只显示预安装或可以运行ACTION_MAIN Intent类型的应用程序。

我也知道我可以使用PackageManager来获取所有已安装的应用程序,但我如何使用它来运行特定的应用程序呢?


当前回答

如果在一个包中有多个启动器,上述代码就有问题。例如:在LG Optimus Facebook为LG, MySpace为LG, Twitter为LG包含在一个包的名称SNS,如果你使用上述SNS将重复。经过几个小时的研究,我得到了以下代码。看起来效果不错。

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

其他回答

另一种过滤系统应用程序的方法(适用于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);
}

这里有一个很好的例子:

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

如果在一个包中有多个启动器,上述代码就有问题。例如:在LG Optimus Facebook为LG, MySpace为LG, Twitter为LG包含在一个包的名称SNS,如果你使用上述SNS将重复。经过几个小时的研究,我得到了以下代码。看起来效果不错。

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

下面是获取Android上安装的活动/应用程序列表的代码:

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

您将在ResolveInfo中获得启动应用程序所需的所有数据。你可以在这里检查ResolveInfo javadoc。

要获得所有已安装的应用程序,您可以使用包管理器

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

要运行一个应用程序,你可以使用它的包名

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

欲了解更多细节,请阅读这个博客http://codebucket.co.in/android-get-list-of-all-installed-apps/