Cómo filtrar aplicaciones específicas para la intención ACTION_SEND (y establecer un texto diferente para cada aplicación)

187

¿Cómo puedes filtrar aplicaciones específicas cuando usas la intención ACTION_SEND? Esta pregunta se ha formulado de varias maneras, pero no he podido reunir una solución basada en las respuestas dadas. Ojalá alguien pueda ayudar. Me gustaría ofrecer la posibilidad de compartir dentro de una aplicación. Siguiendo el consejo de Android Dev Alexander Lucas , prefiero hacerlo usando intenciones y no usando las API de Facebook / Twitter.

Compartir utilizando la intención ACTION_SEND

Compartir usando la intención ACTION_SEND es excelente, pero el problema es (1) No quiero que todas las opciones de intercambio estén allí, prefiero limitarlo a FB, Twitter y Correo electrónico, y (2) No quiero compartir lo mismo para cada aplicación para compartir . Por ejemplo, en mi parte de Twitter voy a incluir algunas menciones y los hashtags lo limitarán a 140 caracteres o menos, mientras que la parte de Facebook incluirá un enlace y una imagen característica.

¿Es posible limitar las opciones para la intención ACTION_SEND (compartir)? He visto algo sobre el uso de PackageManager y queryIntentActivities, pero no he podido descubrir la conexión entre PackageManager y la intención ACTION_SEND.

O

En lugar de filtrar las aplicaciones para compartir, mi problema también podría resolverse si pudiera usar la intención ACTION_SEND para ir directamente a Facebook o Twitter en lugar de abrir el cuadro de diálogo. Si ese fuera el caso, entonces podría crear mi propio cuadro de diálogo y cuando hagan clic en "Facebook" crear una intención específica de Facebook y simplemente enviarlos a Facebook. Lo mismo con Twitter.

¿O acaso no es posible? ¿Son las API de Facebook y Twitter la única forma?

Kyle Clegg
fuente
Posible duplicado: [nombre de paquete personalizado de filtrado de intenciones basado en el nombre de paquete de Android instalado] [1] [1]: stackoverflow.com/questions/5734678/…
Asaf Pinhassi
1
Esta publicación de blog
Vitali Olshevski
2
Hola amigo ... cuando estoy, haga clic en el botón Enviar y luego abra el cuadro de diálogo para compartir y la lista de diálogo para compartir es "gmail, correo electrónico, zapiya, conexión", etc. pero no muestra facebook, whatsapp, facebook messanger, caminatas ... ¿cómo puedo mostrar su ??
GB_Bhayani ツ
¿Cómo no mostrar el selector cuando solo hay un elemento / opción de acción intencional en Android 6.0? el problema no se muestra en menos de Android 6.0
zys

Respuestas:

324

Que yo sepa, StackOverflow tiene muchas personas haciendo esta pregunta de varias maneras, pero nadie la ha respondido por completo todavía.

Mi especificación requería que el usuario pudiera elegir correo electrónico, twitter, facebook o SMS, con texto personalizado para cada uno. Así es como lo logré:

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);       
}

Encontré fragmentos de cómo hacer esto en varios lugares, pero no lo he visto en un solo lugar en ningún otro lugar.

Tenga en cuenta que este método también oculta todas las opciones tontas que no quiero, como compartir a través de wifi y bluetooth.

Espero que esto ayude a alguien.

Editar: en un comentario, me pidieron que explicara qué está haciendo este código. Básicamente, está creando una ACTION_SENDintención SOLAMENTE para el cliente de correo electrónico nativo, luego agrega otras intenciones en el selector. Al hacer la intención original específica del correo electrónico, se eliminan todos los archivos basura adicionales como wifi y bluetooth, luego tomo las otras intenciones que quiero de un ACTION_SENDtexto plano genérico y las agrego antes de mostrar el selector.

Cuando tomo las intenciones adicionales, establezco texto personalizado para cada una.

Edit2: Ha pasado un tiempo desde que publiqué esto, y las cosas han cambiado un poco. Si ve gmail dos veces en la lista de opciones, intente eliminar el manejo especial de "android.gm" como se sugiere en un comentario de @h_k a continuación.

Dado que esta respuesta es la fuente de casi todos mis puntos de reputación de stackoverflow, al menos tengo que tratar de mantenerla actualizada.

dacoinminster
fuente
1
Estoy usando este código, pero de alguna manera evernote se está infiltrando en la lista. Cuando reviso los nombres de los paquetes, es com.evernote, así que no estoy seguro de por qué sucede esto.
James Harpe
1
@ user2249287 Te sugiero que revises el código hasta que veas la aplicación de mensajería que se omite, luego mira el nombre del paquete para determinar qué cadena necesitas agregar a la lista blanca para que aparezca esa aplicación.
dacoinminster
1
@Gilbou Hola! Lo siento, ha pasado mucho tiempo desde que vi este código. . . Como recuerdo, el comando setPackage elige la única intención a la que agregará todo lo demás. Para incluir o excluir varios otros intentos, recomiendo recorrer el código y mirar los nombres de los paquetes.
dacoinminster
2
Para filtrar SOLAMENTE las aplicaciones de correo electrónico que tiene el usuario, puede usar la segunda respuesta de esta pregunta: stackoverflow.com/questions/8701634/send-email-intent . No requiere el uso de un tipo de datos de mensaje / rfc822 que otras aplicaciones, como EverNote en este caso, también usan.
mpellegr
2
@dacoinminster, su código ha sido increíble por permitirme definir diferentes textos para aplicaciones como Twitter y Whatsapp. Para eliminar el gmail duplicado, simplemente saqué "android.gm" de la ecuación. Todavía recibo gmail y la aplicación de correo incorporada en la lista de selección y el asunto y el texto aún están intactos.
h_k
26

Si desea una opción personalizada, no debe confiar en el diálogo predeterminado proporcionado por Android para esta acción.

En su lugar, lo que debe hacer es implementar el suyo. Deberá consultar el PackageManager sobre qué paquetes manejan la acción que necesita y luego, según la respuesta, aplicará el filtrado y el texto personalizado.

Específicamente, eche un vistazo al método queryIntentActivities de la clase PackageManager . Construye la intención que iniciaría el diálogo predeterminado (la intención ACTION_SEND), pasa eso a este método y recibirá una lista de objetos que contienen información sobre las actividades que pueden manejar esa intención. Usando eso, puedes elegir los que quieras.

Una vez que crea su lista de paquetes que desea presentar, debe crear su propio cuadro de diálogo de lista (preferiblemente una actividad con el tema del cuadro de diálogo) que mostrará esa lista.

Sin embargo, una cosa a tener en cuenta es que es muy difícil hacer que ese diálogo personalizado se vea como el predeterminado. El problema es que el tema utilizado en ese diálogo es un tema interno y su aplicación no puede utilizarlo. Puede intentar que sea tan similar al nativo como desee o optar por un aspecto completamente personalizado (muchas aplicaciones hacen eso como la aplicación de galería, etc.)

Savvas Dalkitsis
fuente
1
Marcar esta respuesta correcta ya que responde más de cerca a la pregunta original, aunque terminé yendo por una ruta diferente (vea mi respuesta). Gracias.
Kyle Clegg
22

Pruebe esta para compartir solo tres aplicaciones: 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);
        }
    }
}
usuario3098538
fuente
este código funciona perfectamente si está intentando compartir con aplicaciones específicas
Orcun Sevsay
22

Encontré una solución que funciona para mí mirando aquí (ver el tercer comentario sobre la primera respuesta). Este código busca un cliente de Twitter válido y lo usa para publicar el tweet. Nota: no le da una intención con los distintos clientes de Twitter y le permite elegir.

Compartir usando twitter:

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

Llamando a este método:

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 será similar usando " com.facebook.katana ", aunque todavía no puede configurar el texto del mensaje (en desuso en julio de 2011).

Fuente del código: intención de abrir el cliente de Twitter en Android

Kyle Clegg
fuente
44
No me gusta esta respuesta porque se basa en conocer los nombres de los paquetes de todas las aplicaciones de Twitter. Para otra forma, consulte stackoverflow.com/questions/6827407/…
Ed Burnette
Estoy de acuerdo con usted, aunque la respuesta a la que se vinculó tiene un problema similar. Nunca me gusta confiar en las comparaciones de cadenas, especialmente cuando no tengo control o garantizo que la cadena no cambiará.
Kyle Clegg
11

Gracias a @dacoinminster. Hago algunas modificaciones a su respuesta, incluidos los nombres de paquetes de las aplicaciones populares y la clasificación de esas aplicaciones.

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
fuente
9

Puedes probar el siguiente código, funciona perfectamente.

Aquí compartimos algunas aplicaciones específicas, que son Facebook, Messenger, Twitter, Google Plus y Gmail.

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
fuente
¿Cuál es la razón de "if (name.contains (" com.twitter.android.DMActivity ")) {continue;}?
isJulian00
8

Esta solución muestra una lista de aplicaciones en un cuadro de diálogo ListView que se asemeja al selector:

captura de pantalla

Depende de usted:

  1. obtener la lista de paquetes de aplicaciones relevantes
  2. dado un nombre de paquete, invocar la intención relevante

La clase de adaptador:

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;
    }

}

y su uso:

    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
fuente
4

La forma más limpia es copiar las siguientes clases: ShareActionProvider, ActivityChooserView, ActivityChooserModel. Agregue la capacidad de filtrar las intenciones en ActivityChooserModel y los métodos de soporte apropiados en ShareActionProvider. Creé las clases necesarias, puedes copiarlas en tu proyecto ( https://gist.github.com/saulpower/10557956 ). Esto no solo agrega la capacidad de filtrar las aplicaciones con las que le gustaría compartir (si conoce el nombre del paquete), sino también desactivar el historial.

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
fuente
cómo agregar google + y otras opciones que contienen aplicaciones
remaing
3

He mejorado la respuesta de @dacoinminster y este es el resultado con un ejemplo para compartir su aplicación:

// 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()])));

fuente
3

Tuve el mismo problema y esta solución aceptada no me ayudó, si alguien tiene el mismo problema, puede usar mi fragmento de código:

// 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
fuente
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
fuente
0

Tan simple y conciso. Gracias al desarrollador de código abierto, cketti por compartir esta solución:

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
}

Y este es el enlace a su esencia.

usuario10496632
fuente