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

我试过了:

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

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

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


当前回答

自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权限。

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

点击这里了解更多信息:

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

其他回答

下面是获取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。

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

我需要过滤掉用户并不真正使用的系统应用程序(例如。“com.qualcomm。服务”,“更新服务”等)。最后,我添加了另一个条件来过滤应用程序列表。我只是检查了应用程序是否有“启动意图”。

因此,结果代码看起来像……

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

        }

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

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

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