2013-07-06 54 views
16

我想获得所有出现在菜单屏幕上的应用程序。但是,现在我只获取用户安装的应用程序或所有应用程序(包括系统应用程序)。如何在Android中获取已安装的应用程序并且没有系统应用程序?

我当前的代码是:

final PackageManager pm = getActivity().getPackageManager(); 
    List<PackageInfo> apps = pm.getInstalledPackages(PackageManager.GET_META_DATA); 

    ArrayList<PackageInfo> aux = new ArrayList<PackageInfo>(); 

    for (int i = 0; i < apps.size(); i++) { 
     if (apps.get(i).versionName != null && ((apps.get(i).applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 1)) { 
      aux.add(apps.get(i)); 
     } 

有了这个代码,我可以让用户安装的应用程序,如果我评论的“如果”的指令,我会得到系统应用。

所以,我想获得用户安装的应用程序和应用程序,如联系人,图库等。

UPDATE:

final PackageManager pm = getActivity().getPackageManager(); 
    Intent intent = new Intent(Intent.ACTION_MAIN, null); 
    intent.addCategory(Intent.CATEGORY_LAUNCHER); 
    List<ResolveInfo> apps = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA); 
+2

但接触是系统的应用程序?请解释一下差异。你想要什么样的应用程序列表? – Blundell

+0

我想要列出所有出现在菜单屏幕中的应用程序。 – beni

+0

但联系人出现在菜单屏幕中?即系统应用程序。也许另一个问题会有帮助。什么特定的应用程序*不*你想要的? – Blundell

回答

7
final PackageManager pm = getActivity().getPackageManager(); 
Intent intent = new Intent(Intent.ACTION_MAIN, null); 
intent.addCategory(Intent.CATEGORY_LAUNCHER); 
List<ResolveInfo> apps = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA); 
+1

什么是“GET_META_DATA”?我可以看到ApplicationInfo对象中的“元数据”字段被填充,但它的目的是什么,为什么我们需要它? –

+0

对于安装了许多应用程序的设备,这段代码将抛出TransactionTooLargeException,请检查此答案http:// stackoverflow。com/a/24265790/1245275 – koleanu

+0

@beni,这里我如何跳过带有重复包名称的应用程序? – Manu

35
final PackageManager pm = getPackageManager(); 
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA); 

使用PackageInfo:

private boolean isSystemPackage(PackageInfo packageInfo) { 
    return ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0); 
} 

使用ResolveInfo:

private boolean isSystemPackage(ResolveInfo resolveInfo) { 
    return ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0); 
} 

使用ApplicationInfo:

private boolean isSystemPackage(ApplicationInfo applicationInfo) { 
    return ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0); 
} 

这将过滤系统包。请参阅this问题。学分:尼尔森拉米雷斯和肯尼思埃文斯。

+0

很好的答案! – Opiatefuchs

+0

最好的和真实的答案 –

+0

谢谢你的伟大的 –

1

我有同样的要求。最终我添加了另一个条件来过滤应用程序列表。我刚刚检查了应用程序是否有'启动器意图'。

所以,由此得到的代码看起来像......

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) == 1) { 
        // updated system apps 

       } else if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 1) { 
        // system apps 

       } else { 
        // user installed apps 

       } 
       appsList.add(app); 
      } 

     } 
-1

下面的代码会给你相关的所有操作系统中的系统应用。 这将不包括应用程序,如YouTube,Gmail的,等


try { 
    ApplicationInfo ai = getPackageManager().getApplicationInfo(item.packageName, 0); 
    if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 
     if((ai.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0) { 
     appItem.setSystemApp(true); 
     Mylog.v("System Apps " + appItem.getAppName()); 
     } 
    } 
    } catch (PackageManager.NameNotFoundException e) { 
    e.printStackTrace(); 
    } 
相关问题