2013-07-06 53 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(); 
    } 
相關問題