本周早些时候,我问了一个类似的问题,但我仍然不明白如何获得所有已安装的应用程序的列表,然后选择一个运行。
我试过了:
Intent intent = new Intent(ACTION_MAIN);
intent.addCategory(CATEGORY_LAUNCHER);
这只显示预安装或可以运行ACTION_MAIN Intent类型的应用程序。
我也知道我可以使用PackageManager来获取所有已安装的应用程序,但我如何使用它来运行特定的应用程序呢?
本周早些时候,我问了一个类似的问题,但我仍然不明白如何获得所有已安装的应用程序的列表,然后选择一个运行。
我试过了:
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权限。
在做了上面的事情之后,这里的其他答案仍然适用。
点击这里了解更多信息:
迁移 文档 专用文档页面(有更多 信息) 官方博客 帖子
其他回答
@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;
}
我已经注释了它获取活动名称的部分,但它非常简单。
context.getPackageManager () .getInstalledApplications (PackageManager.GET_META_DATA); 应该返回所有已安装应用程序的列表,但在android 11中,它只返回系统应用程序的列表。要获得所有应用程序(系统+用户)的列表,我们需要为应用程序提供额外的权限
< uses-permission android: name = " android.permission.QUERY_ALL_PACKAGES " / >
干净的解决方案,过滤成功的系统应用程序
这个解决方案背后的思想是,每个系统应用程序的主活动都没有一个自定义的活动图标。这个方法给了我一个很好的结果:
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;
}
自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权限。
在做了上面的事情之后,这里的其他答案仍然适用。
点击这里了解更多信息:
迁移 文档 专用文档页面(有更多 信息) 官方博客 帖子
获取所有应用程序:
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);