À ma connaissance, StackOverflow a beaucoup de gens qui posent cette question de différentes manières, mais personne n'y a encore répondu complètement.
Ma spécification demandait à l'utilisateur de pouvoir choisir l'email, Twitter, Facebook ou SMS, avec un texte personnalisé pour chacun. Voici comment j'ai accompli cela:
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);
}
J'ai trouvé des bouts de comment faire ceci dans divers endroits, mais je n'ai pas vu tout cela dans un endroit nulle part ailleurs.
Notez que cette méthode masque également toutes les options idiotes que je ne veux pas, comme le partage via wifi et bluetooth.
J'espère que cela aide quelqu'un.
Edit:
Dans un commentaire, on m'a demandé d'expliquer ce que fait ce code. Fondamentalement, il crée ACTION_SEND
UNIQUEMENT une intention pour le client de messagerie natif, puis ajoute d'autres intentions au sélecteur. Rendre l'intention d'origine spécifique à l'e-mail élimine tous les indésirables supplémentaires tels que le wifi et le bluetooth, puis je saisis les autres intentions que je veux d'un générique ACTION_SEND
de type texte brut et les cloue avant d'afficher le sélecteur.
Lorsque je saisis les intentions supplémentaires, je définis un texte personnalisé pour chacune.
Edit2: Cela fait un moment que j'ai posté ceci, et les choses ont un peu changé. Si vous voyez gmail deux fois dans la liste des options, essayez de supprimer la gestion spéciale pour "android.gm" comme suggéré dans un commentaire de @h_k ci-dessous.
Étant donné que cette seule réponse est la source de presque tous mes points de réputation de stackoverflow, je dois au moins essayer de la maintenir à jour.