如何获取已安装的Android应用程序列表并选择一个运行

2Re*_*eal 314 android android-intent

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

我试过了:

Intent intent = new Intent(ACTION_MAIN);
intent.addCategory(CATEGORY_LAUNCHER);
Run Code Online (Sandbox Code Playgroud)

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

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

Nel*_*rez 398

这是使用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() 
Run Code Online (Sandbox Code Playgroud)

更多信息,请访问http://qtcstation.com/2011/02/how-to-launch-another-app-from-your-app/


Kar*_*ran 269

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

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

您将获得ResolveInfo启动应用程序中的所有必要数据.你可以在这里查看ResolveInfojavadoc .

  • 我怎样才能开始其中一个?我在ResolveInfo中获得了activityInfo,但我无法启动它. (3认同)
  • 没关系,找到了。我应该使用完整的类名(包 + 类)创建一个新的 Intent。 (2认同)
  • @dowjones123 您是否碰巧找到了有关此的指南? (2认同)

Ken*_*ans 59

过滤系统应用程序的另一种方法(使用上面的示例):

/**
 * 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);
}
Run Code Online (Sandbox Code Playgroud)

  • 返回语句中的"?true:false"部分是多余的 (7认同)
  • 但我过滤设置,地图或......的应用,如何列出它们 (5认同)
  • 这是过滤系统应用程序的最佳答案. (4认同)

kin*_*981 53

这是一个很好的例子:

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; 
}
Run Code Online (Sandbox Code Playgroud)


XXX*_*XXX 33

获取已安装的非系统应用程序列表

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 19

要过滤基于系统的应用:

private boolean isSystemPackage(ResolveInfo ri) {
    return (ri.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
Run Code Online (Sandbox Code Playgroud)


小智 18

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

    List<PackageInfo> apps = getPackageManager().getInstalledPackages(0);
Run Code Online (Sandbox Code Playgroud)

要运行,您可以使用包名称

Intent launchApp = getPackageManager().getLaunchIntentForPackage(“package name”)
startActivity(launchApp);
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请阅读此博客http://codebucket.co.in/android-get-list-of-all-installed-apps/


小智 13

您可以使用以下代码在Android设备中查找已安装应用程序的列表,"packageInfo"包含设备中已安装的应用程序信息.我们可以为从packageinfo对象安装的应用程序检索Intent并使用startactivity(intent),可以启动应用程序.您可以通过Listview或Gridview来组织UI.因此,基于位置的点击事件,您可以检索意图对象并启动活动意图.

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

}
}
Run Code Online (Sandbox Code Playgroud)


joe*_*zac 10

我要求过滤掉用户并不真正使用的系统应用程序(例如"com.qualcomm.service","update services"等).最后,我添加了另一个条件来过滤应用列表.我刚刚检查了该应用是否具有'启动器意图'.

所以,结果代码看起来像......

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

        }
Run Code Online (Sandbox Code Playgroud)


now*_*now 10

自 Android 11(API 级别 30)以来,大多数用户安装的应用默认情况下不可见。您必须静态声明您将在清单中获取有关哪些应用程序和/或意图过滤器的信息,如下所示:

<manifest>
    <queries>
        <!-- Explicit apps you know in advance about: -->
        <package android:name="com.example.this.app"/>
        <package android:name="com.example.this.other.app"/>

        <!-- Intent filter signatures that you are going to query: -->
        <intent>
            <action android:name="android.intent.action.SEND" />
            <data android:mimeType="image/jpeg" />
        </intent>
    </queries>
    
    ...
</manifest>
Run Code Online (Sandbox Code Playgroud)

或者需要QUERY_ALL_PACKAGES许可。

完成上述操作后,这里的其他答案仍然适用。

在这里了解更多:


kak*_*ppa 9

如果一个包中有多个启动器,则上面的代码有问题.例如:在用于LG的LG Optimus Facebook,用于LG的MySpace,用于LG的Twitter包含一个包名称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;
    }
Run Code Online (Sandbox Code Playgroud)


Spi*_*dey 7

@Jas:我已经没有那个代码了,但我发现了一些接近的东西.我已经这样做来搜索我的应用程序的"组件",它们只是具有给定类别的活动.

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;
}
Run Code Online (Sandbox Code Playgroud)

我已经评论了它获取活动名称的部分,但它非常简单.


fun*_*der 6

清洁解决方案,成功过滤系统应用程序

这个解决方案背后的想法是每个系统应用程序的主要活动没有自定义活动图标.这种方法给了我一个很好的结果:

 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;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

context.getPackageManager().getInstalledApplications(PackageManager.GET_META_DATA); 应该返回所有已安装应用程序的列表,但在android 11 中它只会返回系统应用程序列表。要获得所有应用程序(系统+用户)的列表,我们需要为应用程序提供额外的权限,即

<uses-permission android:name"android.permission.QUERY_ALL_PACKAGES">

  • 小更正: &lt;uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/&gt; (3认同)