Benutzerdefinierte Filterung von Intent chooser basierend auf dem installierten Android-Paketnamen

Ich möchte die eingebaute Absichtswähler nutzen, um eine benutzerdefinierte gefilterte Liste von Apps für den Benutzer anzuzeigen, um auszuwählen und zu starten.

Ich weiß, wie man eine Liste der installierten Pakete erhält:

  • Wie kann man ein Bild mit benutzerdefinierter Kamera in Android aufnehmen und speichern?
  • Absichtsfilter für installierte Pakete auflisten
  • LinkedList setzen in Intent extra wird bei ArrayList bei der Wiederherstellung in der nächsten Aktivität umgestaltet
  • Wie kann ich die Absicht löschen?
  • Android: Implizite Intents vs. Broadcast Receiver
  • Übertragen von Daten von einer Aktivität zu einer anderen Aktivität mit Intents
  • final Intent myIntent = new Intent(android.content.Intent.ACTION_MAIN); List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(myIntent, 0); 

    An dieser Stelle möchte ich die Liste auf der Grundlage einer bestimmten String (oder Variation von Strings), die in dem Paketnamen enthalten ist, filtern, was ich auch herausfinden kann, wie es weiter geht.

    Aber hier stehe ich fest Soweit ich weiß, nimmt Intent.createChooser() nur einen einzigen Ziel Intent als Parameter. Ich hatte gehofft, dass es eine Überlastung gab, die eine Liste von Intentionen auf der Grundlage von Paket- und Klassennamen oder so einnahm. Aber so etwas sehe ich nicht Habe ich das irgendwo vermisst?

    Also die Frage ist, ist dies möglich, mit einem eingebauten chooser zu tun, oder muss ich meine eigene mit AlertDialog Builder zu konstruieren? Ich hoffe, das später zu vermeiden.

    Danke im Voraus.

  • Wie werden die Intentionen intern arbeiten?
  • Android Intent für HTTP MP3 Stream auf HTC Incredible
  • Android YouTube App Video abspielen
  • Wie kann man ein Bild mit benutzerdefinierter Kamera in Android aufnehmen und speichern?
  • Was ist packageContext in Intent # (KontextpaketContext, Klasse <?> Cls)?
  • Android - Erkennung der Anwendung starten von zu Hause oder Geschichte
  • 5 Solutions collect form web for “Benutzerdefinierte Filterung von Intent chooser basierend auf dem installierten Android-Paketnamen”

    Der einzige zusätzliche Parameter für den Wähler ist Intent.EXTRA_INITIAL_INTENTS . Seine Beschreibung ist:

    Ein parcelable [] von Intent- oder LabeledIntent-Objekten, wie sie mit putExtra (String, Parcelable []) von zusätzlichen Aktivitäten eingestellt wurden, um die Vorderseite der Auswahlliste zu platzieren, wenn sie dem Benutzer mit einem ACTION_CHOOSER angezeigt wird.

    Ich habe keinen Weg in Android-Quellen gefunden, um andere Aktivitäten aus der Liste auszuschließen, also scheint es, dass es keine Möglichkeit gibt, was du mit dem Wähler machen willst.

    EDIT : Das ist wirklich leicht zu finden. Überprüfe einfach den ChooserActivity und den ResolverActivity Quellcode. Diese Klassen sind eher klein.

    Hier ist eine Lösung, die ich peitschte. Ich benutze es, um unterschiedliche Absichtsdaten für jede Auswahl in der Auswahl zu haben, aber du kannst ganz einfach eine Absicht aus der Liste entfernen. Hoffe das hilft:

     List<Intent> targetedShareIntents = new ArrayList<Intent>(); Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND); shareIntent.setType("text/plain"); List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(shareIntent, 0); if (!resInfo.isEmpty()) { for (ResolveInfo resolveInfo : resInfo) { String packageName = resolveInfo.activityInfo.packageName; Intent targetedShareIntent = new Intent(android.content.Intent.ACTION_SEND); targetedShareIntent.setType("text/plain"); targetedShareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "subject to be shared"); if (TextUtils.equals(packageName, "com.facebook.katana")) { targetedShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "http://link-to-be-shared.com"); } else { targetedShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "text message to shared"); } targetedShareIntent.setPackage(packageName); targetedShareIntents.add(targetedShareIntent); } Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Select app to share"); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[targetedShareIntents.size()])); startActivity(chooserIntent); } 

    BEARBEITEN

    Bei der Verwendung dieser Methode bekomme ich Namen von einigen Apps als Android-System. Wenn jemand diesen Fehler bekommt, fügt man unten Zeilen hinzu, bevor aimtedShareIntents.add targetedShareIntents.add(targetedShareIntent);

      targetedShareIntent.setClassName( resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name); 

    Quelle: Android teilen Absicht Twitter: Wie man nur durch Tweet oder Direct Message zu teilen?

    Ich habe eine kleine Änderung, um eine Liste der Apps, die Sie mit Namen teilen möchten. Es ist fast das, was du bereits gepostet hast, aber das Hinzufügen der Apps zu nennen

     String[] nameOfAppsToShareWith = new String[] { "facebook", "twitter", "gmail" }; String[] blacklist = new String[]{"com.any.package", "net.other.package"}; // your share intent Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, "some text"); intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "a subject"); // ... anything else you want to add invoke custom chooser startActivity(generateCustomChooserIntent(intent, blacklist)); private Intent generateCustomChooserIntent(Intent prototype, String[] forbiddenChoices) { List<Intent> targetedShareIntents = new ArrayList<Intent>(); List<HashMap<String, String>> intentMetaInfo = new ArrayList<HashMap<String, String>>(); Intent chooserIntent; Intent dummy = new Intent(prototype.getAction()); dummy.setType(prototype.getType()); List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(dummy,0); if (!resInfo.isEmpty()) { for (ResolveInfo resolveInfo : resInfo) { if (resolveInfo.activityInfo == null || Arrays.asList(forbiddenChoices).contains( resolveInfo.activityInfo.packageName)) continue; //Get all the posible sharers HashMap<String, String> info = new HashMap<String, String>(); info.put("packageName", resolveInfo.activityInfo.packageName); info.put("className", resolveInfo.activityInfo.name); String appName = String.valueOf(resolveInfo.activityInfo .loadLabel(getPackageManager())); info.put("simpleName", appName); //Add only what we want if (Arrays.asList(nameOfAppsToShareWith).contains( appName.toLowerCase())) { intentMetaInfo.add(info); } } if (!intentMetaInfo.isEmpty()) { // sorting for nice readability Collections.sort(intentMetaInfo, new Comparator<HashMap<String, String>>() { @Override public int compare( HashMap<String, String> map, HashMap<String, String> map2) { return map.get("simpleName").compareTo( map2.get("simpleName")); } }); // create the custom intent list for (HashMap<String, String> metaInfo : intentMetaInfo) { Intent targetedShareIntent = (Intent) prototype.clone(); targetedShareIntent.setPackage(metaInfo.get("packageName")); targetedShareIntent.setClassName( metaInfo.get("packageName"), metaInfo.get("className")); targetedShareIntents.add(targetedShareIntent); } String shareVia = getString(R.string.offer_share_via); String shareTitle = shareVia.substring(0, 1).toUpperCase() + shareVia.substring(1); chooserIntent = Intent.createChooser(targetedShareIntents .remove(targetedShareIntents.size() - 1), shareTitle); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[] {})); return chooserIntent; } } return Intent.createChooser(prototype, getString(R.string.offer_share_via)); } 

    Es ist fast die gleiche Lösung, die Makibo gepostet hat, aber mit einem kleinen Hinzufügen, um eine einfache Form der Kommissionierung der Apps, die Sie teilen möchten, nur durch das Hinzufügen des Namens, so dass Sie kein Problem haben, falls sie den Paketnamen oder so etwas ändern Dies. Solange sie den Namen nicht ändern.

    Meine Umsetzung der benutzerdefinierten offenen chooser.

    Eigenschaften:

    • Apps werden in alphabetischer Reihenfolge sortiert
    • Handhabung der vom Benutzer definierten Standard-App
    • Umgang mit keinem Fall
    • Sich selbst filtern

     public static Intent createOpenFileIntent(Context context, String pathToFile) { File file = new File(pathToFile); String extension = extensionFromName(file.getName()); String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); if (mimeType == null) { //If android doesn't know extension we can check our own list. mimeType = KNOWN_MIME_TYPES.get(DataViewHelper.extensionFromName(file.getName())); } Intent openIntent = new Intent(); openIntent.setAction(android.content.Intent.ACTION_VIEW); openIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); openIntent.setDataAndType(Uri.fromFile(file), mimeType); // 1. Check if there is a default app opener for this type of content. final PackageManager packageManager = context.getPackageManager(); ResolveInfo defaultAppInfo = packageManager.resolveActivity(openIntent, PackageManager.MATCH_DEFAULT_ONLY); if (!defaultAppInfo.activityInfo.name.endsWith("ResolverActivity")) { return openIntent; } // 2. Retrieve all apps for our intent. If there are no apps - return usual already created intent. List<Intent> targetedOpenIntents = new ArrayList<Intent>(); List<ResolveInfo> appInfoList = packageManager.queryIntentActivities(openIntent, PackageManager.MATCH_DEFAULT_ONLY); if (appInfoList.isEmpty()) { return openIntent; } // 3. Sort in alphabetical order, filter itself and create intent with the rest of the apps. Collections.sort(appInfoList, new Comparator<ResolveInfo>() { @Override public int compare(ResolveInfo first, ResolveInfo second) { String firstName = packageManager.getApplicationLabel(first.activityInfo.applicationInfo).toString(); String secondName = packageManager.getApplicationLabel(second.activityInfo.applicationInfo).toString(); return firstName.compareToIgnoreCase(secondName); } }); for (ResolveInfo appInfo : appInfoList) { String packageName = appInfo.activityInfo.packageName; if (packageName.equals(context.getPackageName())) { continue; } Intent targetedOpenIntent = new Intent(android.content.Intent.ACTION_VIEW) .setDataAndType(Uri.fromFile(file), mimeType) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .setPackage(packageName); targetedOpenIntents.add(targetedOpenIntent); } Intent chooserIntent = Intent.createChooser(targetedOpenIntents.remove(targetedOpenIntents.size() - 1), context.getString(R.string.context_menu_open_in)) .putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedOpenIntents.toArray(new Parcelable[] {})); return chooserIntent; } public static String extensionFromName(String fileName) { int dotPosition = fileName.lastIndexOf('.'); // If extension not present or empty if (dotPosition == -1 || dotPosition == fileName.length() - 1) { return ""; } else { return fileName.substring(dotPosition + 1).toLowerCase(Locale.getDefault()); } } 

    Ich habe versucht, dasselbe zu tun, aber mit einem ShareActionProvider. Die Methode in der Post von Gumbercules funktionierte nicht gut mit dem ShareActionProvider, so dass ich die ShareActionProvider-bezogenen Klassen kopiert und modifiziert habe, um eine benutzerdefinierte Filterung der ShareActionProvider-Vorschläge zu ermöglichen.

    Die einzige Änderung ist die ActivityChooserModel.loadActivitiesIfNeeded () – Methode. In meinem Fall wollte ich das YouTube-Paket herausfiltern.

     public static final String YOUTUBE_PACKAGE = "com.google.android.youtube"; private boolean loadActivitiesIfNeeded() { if (mReloadActivities && mIntent != null) { mReloadActivities = false; mActivities.clear(); List<ResolveInfo> resolveInfos = mContext.getPackageManager() .queryIntentActivities(mIntent, 0); final int resolveInfoCount = resolveInfos.size(); for (int i = 0; i < resolveInfoCount; i++) { ResolveInfo resolveInfo = resolveInfos.get(i); // Filter out the YouTube package from the suggestions list if (!resolveInfo.activityInfo.packageName.equals(YOUTUBE_PACKAGE)) { mActivities.add(new ActivityResolveInfo(resolveInfo)); } } return true; } return false; } 

    Code unter https://github.com/danghiskhan/FilteredShareActionProvider

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.