So filtern Sie bestimmte Apps nach ACTION_SEND-Absichten (und legen für jede App einen anderen Text fest)

187

Wie können Sie bestimmte Apps herausfiltern, wenn Sie die Absicht ACTION_SEND verwenden? Diese Frage wurde auf verschiedene Weise gestellt, aber ich konnte auf der Grundlage der gegebenen Antworten keine Lösung finden. Hoffentlich kann jemand helfen. Ich möchte die Möglichkeit bieten, innerhalb einer App zu teilen. Nach dem Rat von Android-Entwickler Alexander Lucas würde ich es vorziehen, dies mit Absichten und nicht mit den Facebook / Twitter-APIs zu tun.

Freigabe mit ACTION_SEND-Absicht

Das Teilen mit der Absicht ACTION_SEND ist großartig, aber das Problem ist, dass (1) ich nicht jede Freigabeoption dort haben möchte, sondern sie lieber auf FB, Twitter und E-Mail beschränken möchte und (2) ich nicht teilen möchte das gleiche für jede Sharing-App . Zum Beispiel werde ich in meiner Twitter-Freigabe einige Erwähnungen und Hashtags auf 140 Zeichen oder weniger beschränken, während die Facebook-Freigabe einen Link und ein Feature-Image enthalten wird.

Ist es möglich, die Optionen für die Absicht ACTION_SEND (Freigabe) einzuschränken? Ich habe etwas über die Verwendung von PackageManager und queryIntentActivities gesehen, konnte jedoch die Verbindung zwischen dem PackageManager und der Absicht ACTION_SEND nicht herausfinden.

ODER

Anstatt die Freigabe-Apps zu filtern, könnte mein Problem auch gelöst werden, wenn ich die Absicht ACTION_SEND verwenden könnte, um direkt zu Facebook oder Twitter zu wechseln, anstatt den Dialog aufzurufen. Wenn dies der Fall wäre, könnte ich meinen eigenen Dialog erstellen und wenn sie auf "Facebook" klicken, eine Facebook-spezifische Absicht erstellen und sie einfach bis zu Facebook senden. Gleiches gilt für Twitter.

ODER ist das nicht möglich? Sind die Facebook- und Twitter-APIs der einzige Weg?

Kyle Clegg
quelle
Mögliches Duplikat: [Benutzerdefinierte Filterung der Absichtsauswahl basierend auf dem installierten Android-Paketnamen] [1] [1]: stackoverflow.com/questions/5734678/…
Asaf Pinhassi
1
Dieser Blogpost scheint die perfekte Antwort zu sein: hkdevtips.blogspot.com/2013/02/…
Vitali
2
Hey Freund ... wenn ich auf meine Schaltfläche "Senden" klicke, dann öffne den Freigabedialog und die Freigabedialogliste lautet "Google Mail, E-Mail, Zapiya, Hookup" usw. aber nicht Facebook, WhatsApp, Facebook Messanger, Wander Treffpunkte ... wie kann ich es zeigen?
GB_Bhayani ツ
Wie kann ich die Auswahl nicht anzeigen, wenn es auf Android 6.0 nur einen Punkt / eine Option für eine Absichtsaktion gibt? Das Problem zeigt sich nicht auf weniger als Android 6.0
zys

Antworten:

324

Meines Wissens hat StackOverflow viele Leute, die diese Frage auf verschiedene Weise stellen, aber noch hat niemand sie vollständig beantwortet.

Meine Spezifikation sah vor, dass der Benutzer E-Mail, Twitter, Facebook oder SMS mit benutzerdefiniertem Text für jeden auswählen kann. So habe ich das erreicht:

public void onShareClick(View v) {
    Resources resources = getResources();

    Intent emailIntent = new Intent();
    emailIntent.setAction(Intent.ACTION_SEND);
    // Native email client doesn't currently support HTML, but it doesn't hurt to try in case they fix it
    emailIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(resources.getString(R.string.share_email_native)));
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, resources.getString(R.string.share_email_subject));
    emailIntent.setType("message/rfc822");

    PackageManager pm = getPackageManager();
    Intent sendIntent = new Intent(Intent.ACTION_SEND);     
    sendIntent.setType("text/plain");


    Intent openInChooser = Intent.createChooser(emailIntent, resources.getString(R.string.share_chooser_text));

    List<ResolveInfo> resInfo = pm.queryIntentActivities(sendIntent, 0);
    List<LabeledIntent> intentList = new ArrayList<LabeledIntent>();        
    for (int i = 0; i < resInfo.size(); i++) {
        // Extract the label, append it, and repackage it in a LabeledIntent
        ResolveInfo ri = resInfo.get(i);
        String packageName = ri.activityInfo.packageName;
        if(packageName.contains("android.email")) {
            emailIntent.setPackage(packageName);
        } else if(packageName.contains("twitter") || packageName.contains("facebook") || packageName.contains("mms") || packageName.contains("android.gm")) {
            Intent intent = new Intent();
            intent.setComponent(new ComponentName(packageName, ri.activityInfo.name));
            intent.setAction(Intent.ACTION_SEND);
            intent.setType("text/plain");
            if(packageName.contains("twitter")) {
                intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_twitter));
            } else if(packageName.contains("facebook")) {
                // Warning: Facebook IGNORES our text. They say "These fields are intended for users to express themselves. Pre-filling these fields erodes the authenticity of the user voice."
                // One workaround is to use the Facebook SDK to post, but that doesn't allow the user to choose how they want to share. We can also make a custom landing page, and the link
                // will show the <meta content ="..."> text from that page with our link in Facebook.
                intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_facebook));
            } else if(packageName.contains("mms")) {
                intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_sms));
            } else if(packageName.contains("android.gm")) { // If Gmail shows up twice, try removing this else-if clause and the reference to "android.gm" above
                intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(resources.getString(R.string.share_email_gmail)));
                intent.putExtra(Intent.EXTRA_SUBJECT, resources.getString(R.string.share_email_subject));               
                intent.setType("message/rfc822");
            }

            intentList.add(new LabeledIntent(intent, packageName, ri.loadLabel(pm), ri.icon));
        }
    }

    // convert intentList to array
    LabeledIntent[] extraIntents = intentList.toArray( new LabeledIntent[ intentList.size() ]);

    openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
    startActivity(openInChooser);       
}

Ich habe an verschiedenen Orten einiges dazu gefunden, aber ich habe nirgendwo anders alles an einem Ort gesehen.

Beachten Sie, dass diese Methode auch alle albernen Optionen verbirgt, die ich nicht möchte, wie z. B. das Teilen über WLAN und Bluetooth.

Hoffe das hilft jemandem.

Bearbeiten: In einem Kommentar wurde ich gebeten zu erklären, was dieser Code tut. Grundsätzlich wird ACTION_SENDNUR eine Absicht für den nativen E-Mail-Client erstellt und dann andere Absichten in die Auswahl übernommen. Wenn Sie die ursprüngliche Absicht per E-Mail festlegen, wird all der zusätzliche Müll wie WLAN und Bluetooth beseitigt. Dann greife ich zu den anderen Absichten, die ich möchte, aus einem generischen ACTION_SENDKlartext und gehe sie an, bevor ich die Auswahl zeige.

Wenn ich die zusätzlichen Absichten ergreife, lege ich für jede einen benutzerdefinierten Text fest.

Edit2: Es ist eine Weile her, seit ich das gepostet habe, und die Dinge haben sich ein bisschen geändert. Wenn Sie Google Mail zweimal in der Liste der Optionen sehen, entfernen Sie die spezielle Behandlung für "android.gm", wie in einem Kommentar von @h_k unten vorgeschlagen.

Da diese eine Antwort die Quelle fast aller meiner Stackoverflow-Reputationspunkte ist, muss ich zumindest versuchen, sie auf dem neuesten Stand zu halten.

dacoinminster
quelle
1
Ich benutze diesen Code, aber irgendwie schleicht sich evernote in die Liste ein. Wenn ich die Paketnamen überprüfe, ist es com.evernote, daher bin ich mir nicht sicher, warum dies geschieht.
James Harpe
1
@ user2249287 Ich würde vorschlagen, dass Sie den Code durchgehen, bis die übersprungene Messaging-App angezeigt wird, und dann anhand des Paketnamens ermitteln, welche Zeichenfolge Sie zur Whitelist dieser App hinzufügen müssen, damit sie angezeigt wird.
Dacoinminster
1
@ Gilbou Hallo! Entschuldigung - es ist lange her, dass ich mir diesen Code angesehen habe. . . Soweit ich mich erinnere, wählt der Befehl setPackage die einzelne Absicht aus, an die Sie alles andere anhängen. Um verschiedene andere Absichten einzuschließen oder auszuschließen, empfehle ich, den Code durchzugehen und die Paketnamen zu überprüfen.
Dacoinminster
2
Um NUR nach den E-Mail-Apps des Benutzers zu filtern, können Sie die zweite Antwort aus dieser Frage verwenden: stackoverflow.com/questions/8701634/send-email-intent . Es ist nicht erforderlich, einen Datentyp von message / rfc822 zu verwenden, den auch andere Apps wie in diesem Fall EverNote verwenden.
mpellegr
2
@dacoinminster Ihr Code war großartig, damit ich unterschiedlichen Text für Apps wie Twitter und WhatsApp definieren konnte. Um das doppelte Google Mail zu entfernen, habe ich einfach "android.gm" aus der Gleichung genommen. Ich erhalte immer noch Google Mail und die integrierte E-Mail-App in der Auswahlliste, und Betreff und Text sind noch intakt.
h_k
26

Wenn Sie eine angepasste Option wünschen, sollten Sie sich für diese Aktion nicht auf das von Android bereitgestellte Standarddialogfeld verlassen.

Was Sie stattdessen tun müssen, ist Ihre eigene auszurollen. Sie müssen den PackageManager abfragen, auf welchen Paketen die von Ihnen gewünschte Aktion ausgeführt wird, und dann basierend auf der Antwort Filterung und benutzerdefinierten Text anwenden.

Schauen Sie sich insbesondere die Methode queryIntentActivities der PackageManager- Klasse an. Sie erstellen die Absicht, die den Standarddialog starten würde (die Absicht ACTION_SEND), übergeben diese an diese Methode und Sie erhalten eine Liste von Objekten, die Informationen zu den Aktivitäten enthalten, die diese Absicht verarbeiten können. Damit können Sie die gewünschten auswählen.

Sobald Sie Ihre Liste der Pakete erstellt haben, die Sie präsentieren möchten, müssen Sie einen eigenen Listendialog erstellen (vorzugsweise eine Aktivität mit dem Dialogthema), in dem diese Liste angezeigt wird.

Eine Sache, die zu beachten ist, ist, dass es sehr schwierig ist, diesen benutzerdefinierten Dialog wie den Standarddialog aussehen zu lassen. Das Problem ist, dass das in diesem Dialogfeld verwendete Thema ein internes Thema ist und von Ihrer Anwendung nicht verwendet werden kann. Sie können entweder versuchen, es dem nativen so ähnlich zu machen, wie Sie möchten, oder einen vollständig benutzerdefinierten Look wählen (viele Apps tun dies wie die Galerie-App usw.).

Savvas Dalkitsis
quelle
1
Markieren Sie diese Antwort als richtig, da sie die ursprüngliche Frage am besten beantwortet, obwohl ich einen anderen Weg eingeschlagen habe (siehe meine Antwort). Vielen Dank.
Kyle Clegg
22

Probieren Sie diese aus, um nur drei Apps zu teilen - Facebook, Twitter, KakaoStory.

public void onShareClick(View v){
    List<Intent> targetShareIntents=new ArrayList<Intent>();
    Intent shareIntent=new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.setType("text/plain");
    List<ResolveInfo> resInfos=getPackageManager().queryIntentActivities(shareIntent, 0);
    if(!resInfos.isEmpty()){
        System.out.println("Have package");
        for(ResolveInfo resInfo : resInfos){
            String packageName=resInfo.activityInfo.packageName;
            Log.i("Package Name", packageName);
            if(packageName.contains("com.twitter.android") || packageName.contains("com.facebook.katana") || packageName.contains("com.kakao.story")){
                Intent intent=new Intent();
                intent.setComponent(new ComponentName(packageName, resInfo.activityInfo.name));
                intent.setAction(Intent.ACTION_SEND);
                intent.setType("text/plain");
                intent.putExtra(Intent.EXTRA_TEXT, "Text");
                intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
                intent.setPackage(packageName);
                targetShareIntents.add(intent);
            }
        }
        if(!targetShareIntents.isEmpty()){
            System.out.println("Have Intent");
            Intent chooserIntent=Intent.createChooser(targetShareIntents.remove(0), "Choose app to share");
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetShareIntents.toArray(new Parcelable[]{}));
            startActivity(chooserIntent);
        }else{
            System.out.println("Do not Have Intent");
            showDialaog(this);
        }
    }
}
user3098538
quelle
Dieser Code funktioniert perfekt, wenn Sie versuchen, mit bestimmten Apps zu teilen
Orcun Sevsay
22

Ich habe hier eine Lösung gefunden, die für mich funktioniert (siehe den dritten Kommentar zur ersten Antwort). Dieser Code sucht nach einem gültigen Twitter-Client und verwendet ihn zum Posten des Tweets. Hinweis: Sie erhalten keine Absicht mit den verschiedenen Twitter-Clients und können auswählen.

Mit Twitter teilen:

Intent shareIntent = findTwitterClient(); 
shareIntent.putExtra(Intent.EXTRA_TEXT, "test");
startActivity(Intent.createChooser(shareIntent, "Share"));

Aufruf dieser Methode:

public Intent findTwitterClient() {
    final String[] twitterApps = {
            // package // name - nb installs (thousands)
            "com.twitter.android", // official - 10 000
            "com.twidroid", // twidroid - 5 000
            "com.handmark.tweetcaster", // Tweecaster - 5 000
            "com.thedeck.android" }; // TweetDeck - 5 000 };
    Intent tweetIntent = new Intent();
    tweetIntent.setType("text/plain");
    final PackageManager packageManager = getPackageManager();
    List<ResolveInfo> list = packageManager.queryIntentActivities(
            tweetIntent, PackageManager.MATCH_DEFAULT_ONLY);

    for (int i = 0; i < twitterApps.length; i++) {
        for (ResolveInfo resolveInfo : list) {
            String p = resolveInfo.activityInfo.packageName;
            if (p != null && p.startsWith(twitterApps[i])) {
                tweetIntent.setPackage(p);
                return tweetIntent;
            }
        }
    }

    return null;
}

Facebook wird mit " com.facebook.katana " ähnlich sein , obwohl Sie den Nachrichtentext immer noch nicht festlegen können (veraltet im Juli 2011).

Codequelle: Absicht, den Twitter-Client auf Android zu öffnen

Kyle Clegg
quelle
4
Diese Antwort gefällt mir nicht, da sie davon abhängt, die Paketnamen aller Twitter-Apps zu kennen. Für einen anderen Weg siehe stackoverflow.com/questions/6827407/…
Ed Burnette
Ich stimme Ihnen zu, obwohl die Antwort, auf die Sie verlinkt haben, ein ähnliches Problem hat. Ich verlasse mich nie gerne auf String-Vergleiche, besonders wenn ich keine Kontrolle habe oder garantiere, dass sich der String nicht ändert.
Kyle Clegg
11

Vielen Dank an @dacoinminster. Ich nehme einige Änderungen an seiner Antwort vor, einschließlich der Paketnamen der beliebten Apps und der Sortierung dieser Apps.

List<Intent> targetShareIntents = new ArrayList<Intent>();
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
PackageManager pm = getActivity().getPackageManager();
List<ResolveInfo> resInfos = pm.queryIntentActivities(shareIntent, 0);
if (!resInfos.isEmpty()) {
    System.out.println("Have package");
    for (ResolveInfo resInfo : resInfos) {
        String packageName = resInfo.activityInfo.packageName;
        Log.i("Package Name", packageName);

        if (packageName.contains("com.twitter.android") || packageName.contains("com.facebook.katana")
                || packageName.contains("com.whatsapp") || packageName.contains("com.google.android.apps.plus")
                || packageName.contains("com.google.android.talk") || packageName.contains("com.slack")
                || packageName.contains("com.google.android.gm") || packageName.contains("com.facebook.orca")
                || packageName.contains("com.yahoo.mobile") || packageName.contains("com.skype.raider")
                || packageName.contains("com.android.mms")|| packageName.contains("com.linkedin.android")
                || packageName.contains("com.google.android.apps.messaging")) {
            Intent intent = new Intent();

            intent.setComponent(new ComponentName(packageName, resInfo.activityInfo.name));
            intent.putExtra("AppName", resInfo.loadLabel(pm).toString());
            intent.setAction(Intent.ACTION_SEND);
            intent.setType("text/plain");
            intent.putExtra(Intent.EXTRA_TEXT, "https://website.com/");
            intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_text));
            intent.setPackage(packageName);
            targetShareIntents.add(intent);
        }
    }
    if (!targetShareIntents.isEmpty()) {
        Collections.sort(targetShareIntents, new Comparator<Intent>() {
            @Override
            public int compare(Intent o1, Intent o2) {
                return o1.getStringExtra("AppName").compareTo(o2.getStringExtra("AppName"));
            }
        });
        Intent chooserIntent = Intent.createChooser(targetShareIntents.remove(0), "Select app to share");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetShareIntents.toArray(new Parcelable[]{}));
        startActivity(chooserIntent);
    } else {
        Toast.makeText(getActivity(), "No app to share.", Toast.LENGTH_LONG).show();
    }
}
Oguz Ozcan
quelle
9

Sie können den folgenden Code ausprobieren, er funktioniert einwandfrei.

Hier teilen wir einige spezifische Apps mit, nämlich Facebook, Messenger, Twitter, Google Plus und Google Mail.

public void shareIntentSpecificApps() {
        List<Intent> intentShareList = new ArrayList<Intent>();
        Intent shareIntent = new Intent();
        shareIntent.setAction(Intent.ACTION_SEND);
        shareIntent.setType("text/plain");
        List<ResolveInfo> resolveInfoList = getPackageManager().queryIntentActivities(shareIntent, 0);

        for (ResolveInfo resInfo : resolveInfoList) {
            String packageName = resInfo.activityInfo.packageName;
            String name = resInfo.activityInfo.name;
            Log.d(TAG, "Package Name : " + packageName);
            Log.d(TAG, "Name : " + name);

            if (packageName.contains("com.facebook") ||
                    packageName.contains("com.twitter.android") ||
                    packageName.contains("com.google.android.apps.plus") ||
                    packageName.contains("com.google.android.gm")) {

                if (name.contains("com.twitter.android.DMActivity")) {
                    continue;
                }

                Intent intent = new Intent();
                intent.setComponent(new ComponentName(packageName, name));
                intent.setAction(Intent.ACTION_SEND);
                intent.setType("text/plain");
                intent.putExtra(Intent.EXTRA_SUBJECT, "Your Subject");
                intent.putExtra(Intent.EXTRA_TEXT, "Your Content");
                intentShareList.add(intent);
            }
        }

        if (intentShareList.isEmpty()) {
            Toast.makeText(MainActivity.this, "No apps to share !", Toast.LENGTH_SHORT).show();
        } else {
            Intent chooserIntent = Intent.createChooser(intentShareList.remove(0), "Share via");
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentShareList.toArray(new Parcelable[]{}));
            startActivity(chooserIntent);
        }
    }
Dang Nguyen
quelle
Was ist der Grund für "if (name.contains (" com.twitter.android.DMActivity ")) {continue;}?
isJulian00
8

Diese Lösung zeigt eine Liste von Anwendungen in einem ListView-Dialogfeld an, die der Auswahl ähnelt:

Bildschirmfoto

Es liegt an Ihnen:

  1. Erhalten Sie die Liste der relevanten Anwendungspakete
  2. Rufen Sie unter Angabe eines Paketnamens die entsprechende Absicht auf

Die Adapterklasse:

import java.util.List;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class ChooserArrayAdapter extends ArrayAdapter<String> {
    PackageManager mPm;
    int mTextViewResourceId;
    List<String> mPackages;

    public ChooserArrayAdapter(Context context, int resource, int textViewResourceId, List<String> packages) {
        super(context, resource, textViewResourceId, packages);
        mPm = context.getPackageManager();
        mTextViewResourceId = textViewResourceId;
        mPackages = packages;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        String pkg = mPackages.get(position);
        View view = super.getView(position, convertView, parent);

        try {
            ApplicationInfo ai = mPm.getApplicationInfo(pkg, 0);

            CharSequence appName = mPm.getApplicationLabel(ai);
            Drawable appIcon = mPm.getApplicationIcon(pkg);

            TextView textView = (TextView) view.findViewById(mTextViewResourceId);
            textView.setText(appName);
            textView.setCompoundDrawablesWithIntrinsicBounds(appIcon, null, null, null);
            textView.setCompoundDrawablePadding((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, getContext().getResources().getDisplayMetrics()));
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }

        return view;
    }

}

und seine Verwendung:

    void doXxxButton() {
        final List<String> packages = ...;
        if (packages.size() > 1) {
            ArrayAdapter<String> adapter = new ChooserArrayAdapter(MyActivity.this, android.R.layout.select_dialog_item, android.R.id.text1, packages);

            new AlertDialog.Builder(MyActivity.this)
            .setTitle(R.string.app_list_title)
            .setAdapter(adapter, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int item ) {
                    invokeApplication(packages.get(item));
                }
            })
            .show();
        } else if (packages.size() == 1) {
            invokeApplication(packages.get(0));
        }
    }

    void invokeApplication(String packageName) {
        // given a package name, create an intent and fill it with data
        ...
        startActivityForResult(intent, rq);
    }
18446744073709551615
quelle
4

Am saubersten ist es, die folgenden Klassen zu kopieren: ShareActionProvider, ActivityChooserView, ActivityChooserModel. Fügen Sie die Möglichkeit hinzu, die Absichten im ActivityChooserModel und die entsprechenden Unterstützungsmethoden im ShareActionProvider zu filtern. Ich habe die erforderlichen Klassen erstellt. Sie können sie in Ihr Projekt kopieren ( https://gist.github.com/saulpower/10557956 ). Dies bietet nicht nur die Möglichkeit, die Apps zu filtern, mit denen Sie teilen möchten (wenn Sie den Paketnamen kennen), sondern auch den Verlauf zu deaktivieren.

private final String[] INTENT_FILTER = new String[] {
    "com.twitter.android",
    "com.facebook.katana"
};

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.journal_entry_menu, menu);

    // Set up ShareActionProvider's default share intent
    MenuItem shareItem = menu.findItem(R.id.action_share);

    if (shareItem instanceof SupportMenuItem) {
        mShareActionProvider = new ShareActionProvider(this);
        mShareActionProvider.setShareIntent(ShareUtils.share(mJournalEntry));
        mShareActionProvider.setIntentFilter(Arrays.asList(INTENT_FILTER));
        mShareActionProvider.setShowHistory(false);
        ((SupportMenuItem) shareItem).setSupportActionProvider(mShareActionProvider);
    }

    return super.onCreateOptionsMenu(menu);
}
saulpower
quelle
wie man Google + und andere Optionen hinzufügt, die verbleibende Anwendungen enthalten
Sunishtha Singh
3

Ich habe die Antwort von @dacoinminster verbessert und dies ist das Ergebnis mit einem Beispiel zum Teilen Ihrer App:

// Intents with SEND action
PackageManager packageManager = context.getPackageManager();
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(sendIntent, 0);

List<LabeledIntent> intentList = new ArrayList<LabeledIntent>();
Resources resources = context.getResources();

for (int j = 0; j < resolveInfoList.size(); j++) {
    ResolveInfo resolveInfo = resolveInfoList.get(j);
    String packageName = resolveInfo.activityInfo.packageName;
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_SEND);
    intent.setComponent(new ComponentName(packageName,
    resolveInfo.activityInfo.name));
    intent.setType("text/plain");

    if (packageName.contains("twitter")) {
        intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.twitter) + "https://play.google.com/store/apps/details?id=" + context.getPackageName());
    } else {
        // skip android mail and gmail to avoid adding to the list twice
        if (packageName.contains("android.email") || packageName.contains("android.gm")) {
            continue;
        }
        intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.largeTextForFacebookWhatsapp) + "https://play.google.com/store/apps/details?id=" + context.getPackageName());
    }

    intentList.add(new LabeledIntent(intent, packageName, resolveInfo.loadLabel(packageManager), resolveInfo.icon));
}

Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, resources.getString(R.string.subjectForMailApps));
emailIntent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.largeTextForMailApps) + "https://play.google.com/store/apps/details?id=" + context.getPackageName());

context.startActivity(Intent.createChooser(emailIntent, resources.getString(R.string.compartirEn)).putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new LabeledIntent[intentList.size()])));

quelle
3

Ich hatte das gleiche Problem und diese akzeptierte Lösung hat mir nicht geholfen. Wenn jemand das gleiche Problem hat, können Sie mein Code-Snippet verwenden:

// example of filtering and sharing multiple images with texts
// remove facebook from sharing intents
private void shareFilter(){

    String share = getShareTexts();
    ArrayList<Uri> uris = getImageUris();

    List<Intent> targets = new ArrayList<>();
    Intent template = new Intent(Intent.ACTION_SEND_MULTIPLE);
    template.setType("image/*");
    List<ResolveInfo> candidates = getActivity().getPackageManager().
            queryIntentActivities(template, 0);

    // remove facebook which has a broken share intent
    for (ResolveInfo candidate : candidates) {
        String packageName = candidate.activityInfo.packageName;
        if (!packageName.equals("com.facebook.katana")) {
            Intent target = new Intent(Intent.ACTION_SEND_MULTIPLE);
            target.setType("image/*");
            target.putParcelableArrayListExtra(Intent.EXTRA_STREAM,uris);
            target.putExtra(Intent.EXTRA_TEXT, share);
            target.setPackage(packageName);
            targets.add(target);
        }
    }
    Intent chooser = Intent.createChooser(targets.remove(0), "Share Via");
    chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targets.toArray(new Parcelable[targets.size()]));
    startActivity(chooser);

}
jemo mgebrishvili
quelle
3
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, 
    Uri.fromParts("mailto", "[email protected]", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, text);
startActivity(Intent.createChooser(emailIntent, "Send email..."));
Murugan
quelle
0

So einfach und prägnant. Dank des Open Source-Entwicklers cketti für die Freigabe dieser Lösung:

String mailto = "mailto:[email protected]" +
    "?cc=" + "[email protected]" +
    "&subject=" + Uri.encode(subject) +
    "&body=" + Uri.encode(bodyText);

Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse(mailto));

try {
  startActivity(emailIntent);
} catch (ActivityNotFoundException e) {
  //TODO: Handle case where no email app is available
}

Und dies ist die Verbindung zu seinem Kern.

user10496632
quelle