2012-03-28 11 views
23

Ich schreibe eine App, mit der Benutzer die Liste der installierten Apps anzeigen können, wählen Sie eine von ihnen und starten Sie es dann nach Plan. Unter Verwendung von Tutorials von stackoverflow habe ich herausgefunden, wie man eine Liste installierter Aktivitäten, deren Paketnamen und Symbole erhält (d. H. here - mehrere Möglichkeiten, dies zu tun). Nur für den Fall, das ist, wie ich Aktivitäten beginnen, es funktioniert einwandfrei, kein Problem hier:Android: So erhalten Sie eine Liste der installierten Aktivitäten, wie sie im Launcher erscheinen, ohne Duplikate

Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName); 
launchIntent.setAction(Intent.ACTION_MAIN); 
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); 
launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(launchIntent); 

Das Problem ist, mit einer Liste der installierten Anwendungen abzurufen. Ich habe zwei Wege gefunden, um eine Liste der installierten Anwendungen zu erhalten:

1) verwenden

PackageManager pm = getPackageManager(); 
List<ApplicationInfo> apps = pm.getInstalledApplication(PackageManager.GET_META_DATA) 

und von jedem Element aus apps können Sie bekommen es Paketnamen und Paketaufkleber (App-Namen).

2) verwenden

PackageManager pm = getPackageManager();  
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); 
List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(mainIntent, 0); 
for(ResolveInfo info : resolveInfos) { 
    ApplicationInfo applicationInfo = info.activityInfo.applicationInfo; 
    //... 
    //get package name, icon and label from applicationInfo object  
} 

Es gibt ein Problem mit ersten Methode: es gibt alle installierten Pakete, einschließlich der Systemdienste, die keine Aktivität enthalten und sind daher nicht startbar. Hier ist ein Screenshot mit einem Beispiel: app list with packages

Alle oben genannten Elemente, die keine Symbole haben, sind nicht startbar.

Es gibt ein Problem mit dem auch zweiten Ansatz ist: Mehrere Elemente in der Liste Duplikate haben: app list with duplicates

Wenn ich einen Haltepunkt in Debugger einrichten ich sehe, dass diese „Maps“ Artikel anders haben Aktivitätsnamen ("com.google.android.maps.MapsActivity", "com.google.android.maps.LatitudeActivity", "com.google.android.maps.PlacesActivity" usw.).

Ich entschied mich, den zweiten Ansatz zu verwenden, weil es eine Liste gibt, die für meine Bedürfnisse besser geeignet ist, aber ich finde keine Möglichkeit, die Duplikate herauszufiltern und nur die Standardaktivität für die App anzuzeigen erscheinen im Launcher (Sie sehen nur einen "Maps" in der App-Liste Ihres Telefons, nicht vier). Ich habe versucht, System-Apps durch ApplicationInfo.FLAG_SYSTEM herauszufiltern, aber das entfernt viele Apps, die ich haben möchte, einschließlich Karten und anderen vorinstallierten Apps. Ich habe versucht, PackageManager.MATCH_DEFAULT_ONLY Flag bei der Ausführung von queryIntentActivities, aber das filtert auch viele Anwendungen aus, so dass nur einige wenige.

Ich bin hier irgendwie verloren, und ich weiß nicht, was zu tun ist. Ich habe alle Fragen zu stackoverflow über das Abrufen einer Liste von installierten Apps gelesen, aber dieses Problem wurde noch nie aufgeworfen. Bitte, hilf irgendjemandem? Wie kann ich eine Liste der installierten abschaltbaren Apps abrufen, die keine Duplikate enthalten?

+0

Sie sagen, dass "diese Frage wurde nie gebracht". Bitte überprüfen Sie dies, vielleicht hilft es: http://stackoverflow.com/questions/4598769/list-of-user-installed-apps/4599124#4599124 – Zelimir

+1

Ich meinte Duplikate in der Liste, ich habe niemanden gesehen, der dies erwähnt. Ja, ich habe diesen Kommentar gesehen. Ich habe versucht, Apps mit 'ApplicationInfo.FLAG_SYSTEM' zu überspringen, aber aus irgendeinem Grund werden dadurch viele gültige Apps entfernt, einschließlich Spiele und ähnliches. –

Antwort

13
Intent localIntent2 = new Intent("android.intent.action.PICK_ACTIVITY"); 
Intent localIntent3 = new Intent("android.intent.action.MAIN",null); 
localIntent3.addCategory("android.intent.category.LAUNCHER"); 
localIntent2.putExtra("android.intent.extra.INTENT",localIntent3); 
startActivityForResult(localIntent2, 1); 

diesen Code Versuchen. Es werden nur die Anwendungen aufgelistet, die alle auf Ihrem Gerät installiert sind.

+0

Ja, es hat funktioniert! Vielen Dank! –

+0

es funktioniert, aber das wird effektiver sein, wenn Sie die ausgewählte App ausführen können. Denn ab jetzt, wenn Sie eine App auswählen, ist nichts passiert. –

+1

gute Antwort, aber vermeiden Sie hartcodierte Zeichenketten ussing, stattdessen verwenden Sie Konstanten, wie Intent.EXTRA_INTENT für "android.intent.extra.INTENT". –

6

Versuchen Sie unter Code und lassen Sie mich wissen, was passiert ist.

PackageManager manager = getPackageManager(); 
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); 

List<ResolveInfo> resolveInfos= manager.queryIntentActivities(mainIntent, 0); 
// Below line is new code i added to your code 
Collections.sort(resolveInfos, new ResolveInfo.DisplayNameComparator(manager)); 

for(ResolveInfo info : resolveInfos) { 
    ApplicationInfo applicationInfo = info.activityInfo.applicationInfo; 
    //... 
    //get package name, icon and label from applicationInfo object  
} 
+0

Hallo, hier ist ein Screenshot von dem, was passiert ist: http://i.stack.imgur.com/xCXqY.png Es gibt noch 4 'Maps' in der Liste, aber jetzt sind sie in zufälliger Reihenfolge. –

13

Ich könnte zu spät kommen, aber ich fand nur eine perfekte Möglichkeit, alle Anwendungen mit Launcher & keine doppelten Apps (einschließlich System-Apps wie Kontakte, Karten, etc.) zu bekommen. Obwohl die Antwort von Satheesh funktionieren könnte (habe mich selbst nicht überprüft), aber ich wollte mehrere Aktivitäten auswählen, also habe ich unten Code verwendet, um installierte Apps zu bekommen.

Ich benutzte Ihre zweite Methode und verworfen doppelte Pakete mit HashSet. Hier ist der endgültige Code:

final PackageManager packageManager = getPackageManager(); 
    Intent intent = new Intent(Intent.ACTION_MAIN, null); 
    intent.addCategory(Intent.CATEGORY_LAUNCHER); 
    List<ResolveInfo> resInfos = packageManager.queryIntentActivities(intent, 0); 
    //using hashset so that there will be no duplicate packages, 
    //if no duplicate packages then there will be no duplicate apps 
    HashSet<String> packageNames = new HashSet<String>(0); 
    List<ApplicationInfo> appInfos = new ArrayList<ApplicationInfo>(0); 

    //getting package names and adding them to the hashset 
    for(ResolveInfo resolveInfo : resInfos) { 
     packageNames.add(resolveInfo.activityInfo.packageName); 
    } 

    //now we have unique packages in the hashset, so get their application infos 
    //and add them to the arraylist 
    for(String packageName : packageNames) { 
     try { 
      appInfos.add(packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)); 
     } catch (NameNotFoundException e) { 
      //Do Nothing 
     } 
    } 

    //to sort the list of apps by their names 
    Collections.sort(appInfos, new ApplicationInfo.DisplayNameComparator(packageManager)); 
3

ich die gleiche Forderung hatte. Letztendlich habe ich eine weitere Bedingung hinzugefügt, um die App-Liste herunterzufiltern. Ich habe gerade überprüft, ob die App 'Launcher Intent' hat.

So sieht der resultierende Code wie ...

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

Beide @Ashish Tanna und jozze sind richtig, aber die Leistung vielleicht ein kleines Problem.

Dies ist die beste Leistung.

Set<String> packageNameSet = new HashSet<>(); 
PackageManager pm = context.getPackageManager(); 
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); 
List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(mainIntent, 0); 
for(ResolveInfo info : resolveInfos) { 
    // be added 
    ApplicationInfo applicationInfo; 
    if (info == null || (applicationInfo = info.activityInfo.applicationInfo) == null 
      || !applicationInfo.enabled || packageNameSet.contains(applicationInfo.packageName)) { 
     continue; 
    } 
    packageNameSet.add(applicationInfo.packageName); 

    //... 
    //get package name, icon and label from applicationInfo object 
} 

(1) hinzufügen HashSet (2) Richter, ob die Anwendung aktiviert ist (3) Beurteilen, ob innerhalb des Hashset hat

Verwandte Themen