如何获得安装的Android应用程序的列表,并select一个运行
我在本周早些时候提出了一个类似的问题,但我仍然不知道如何获得所有安装的应用程序的列表,然后select一个运行。
我试过了:
Intent intent = new Intent(ACTION_MAIN); intent.addCategory(CATEGORY_LAUNCHER);
这只显示预安装的应用程序或者可以运行ACTION_MAIN意图types的应用程序。
我也知道我可以使用PackageManager来获取所有已安装的应用程序,但是如何使用它来运行特定的应用程序?
以下是获取安装在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。
HTH!
这是使用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/
另一种在系统应用程序上进行过滤的方法(适用于上面的例子):
/** * Return whether the given PackgeInfo 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) ? true : false; }
这里有个很好的例子:
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; }
获取已安装的非系统应用程序的列表
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); } } }
要过滤基于系统的应用程序:
private boolean isSystemPackage(ResolveInfo ri) { return (ri.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; }
要获得安装的应用程序,您可以使用软件包pipe理器
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/
您可以使用以下代码在“Android设备”中find已安装的应用程序列表,“packageInfo”包含已安装的设备中的应用程序信息。 我们可以检索从packageinfo对象安装的应用程序的意图,并通过使用startactivity(意图),可以启动应用程序。 这取决于你如何组织UI ListView或Gridview。 所以基于位置的点击事件,您可以回顾意向对象并启动活动意图。
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++; } }
如果上面的一个包中有多个发射器,则代码有问题。 例如:在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; }
@Jas:我没有这个代码,但是我发现了一些东西。 我已经做了这个search我的应用程序的“组件”,他们只是一个给定类别的活动。
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; }
我已经评论了获取活动名称的部分,但是非常简单。
清理解决scheme,成功过滤系统应用程序
这个解决scheme背后的想法是,每个系统应用程序的主要活动没有自定义活动图标 。 这个方法给了我一个很好的结果:
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; }
我有一个要求,过滤出用户不真正使用的系统应用程序(例如“com.qualcomm.service”,“更新服务”等)。 最终我添加了另一个条件来过滤应用程序列表。 我只是检查应用程序是否有“启动意图”。
所以,结果代码看起来像…
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); } }
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; } }
我有另一个解决scheme:
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 } }