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

我试过了:

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

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

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


当前回答

这里有一个很好的例子:

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

其他回答

获取所有应用程序:

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

检查是否安装了应用程序,然后打开:

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

下面是使用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() 

更多信息请点击这里http://qtcstation.com/2011/02/how-to-launch-another-app-from-your-app/

我有另一个解决方案:

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

你可以用这个:

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

自Android 11 (API级别30)以来,大多数用户安装的应用默认是不可见的。你必须静态地声明哪些应用程序和/或意图过滤器你将在你的manifest中获得信息,就像这样:

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

或者要求QUERY_ALL_PACKAGES权限。

在做了上面的事情之后,这里的其他答案仍然适用。

点击这里了解更多信息:

迁移 文档 专用文档页面(有更多 信息) 官方博客 帖子