À ma connaissance, sur StackOverflow, de nombreuses personnes ont posé cette question de différentes manières, mais personne n'y a encore répondu complètement.
Mon cahier des charges prévoyait que l'utilisateur puisse choisir entre email, twitter, facebook ou SMS, avec un texte personnalisé pour chacun d'eux. Voici comment j'ai réalisé 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 éléments sur la façon de procéder à divers endroits, mais je n'ai pas vu tout cela en un seul endroit.
Notez que cette méthode masque également toutes les options stupides dont je ne veux pas, comme le partage par wifi et bluetooth.
J'espère que cela aidera quelqu'un.
Edit : Dans un commentaire, on m'a demandé d'expliquer ce que fait ce code. En gros, il crée un ACTION_SEND
pour le client de messagerie natif UNIQUEMENT, puis en ajoutant d'autres intentions au sélecteur. Le fait de rendre l'intention originale spécifique au courrier électronique permet de se débarrasser de tous les éléments superflus comme le wifi et le bluetooth, puis je récupère les autres intents que je veux dans un sélecteur générique. ACTION_SEND
de type plain-text, et les ajouter avant de les montrer au sélecteur.
Lorsque je saisis les intentions supplémentaires, je définis un texte personnalisé pour chacune d'elles.
Edit2 : Cela fait longtemps que je n'ai pas posté ce message, et les choses ont un peu changé. Si vous voyez deux fois gmail dans la liste des options, essayez de supprimer le traitement spécial pour "Android.gm" comme suggéré dans un commentaire de @h_k ci-dessous.
Puisque cette seule réponse est la source de presque tous mes points de réputation sur stackoverflow, je dois au moins essayer de la tenir à jour.
0 votes
Duplicata possible : [custom-filtering-of-intent-chooser-based-on-installed-android-package-name][1] [1] : stackoverflow.com/questions/5734678/
1 votes
Ce billet de blog semble être la réponse parfaite : hkdevtips.blogspot.com/2013/02/
2 votes
Hey ami... quand je clique sur mon bouton d'envoi puis ouvre le dialogue de partage et la liste du dialogue de partage est "gmail ,email ,zapiya , hookup "etc. mais ne montre pas facebook ,whatsapp,facebook messanger ,hike hangouts ... comment puis-je montrer son ? ?
0 votes
Comment ne pas afficher le sélecteur lorsqu'il n'y a qu'un seul élément/option d'une action intentionnelle sous Android 6.0 ? Le problème ne se pose pas sous Android 6.0.