Como filtrar aplicativos específicos para a intenção de ACTION_SEND (e definir um texto diferente para cada aplicativo)

187

Como você pode filtrar aplicativos específicos ao usar a intenção ACTION_SEND? Esta pergunta foi feita de várias maneiras, mas não consegui reunir uma solução com base nas respostas dadas. Espero que alguém possa ajudar. Gostaria de fornecer a capacidade de compartilhar dentro de um aplicativo. Seguindo o conselho do Android Dev Alexander Lucas , eu preferiria fazê-lo usando intenções e não usando as APIs do Facebook / Twitter.

Compartilhando usando a intenção de ACTION_SEND

Compartilhar usando a intenção ACTION_SEND é ótimo, mas o problema é (1) não quero todas as opções de compartilhamento lá, prefiro limitá-las ao FB, Twitter e e-mail e (2) não quero compartilhar a mesma coisa para cada aplicativo de compartilhamento . Por exemplo, no meu compartilhamento no twitter, incluirei algumas menções e hashtags limitadas a 140 caracteres ou menos, enquanto o compartilhamento no facebook incluirá um link e uma imagem de recurso.

É possível limitar as opções para a intenção de ACTION_SEND (compartilhamento)? Eu já vi algo sobre o uso de PackageManager e queryIntentActivities, mas não consegui descobrir a conexão entre o PackageManager e a intenção ACTION_SEND.

OU

Em vez de filtrar os aplicativos de compartilhamento, meu problema também poderia ser resolvido se eu pudesse usar a intenção de ACTION_SEND de ir diretamente para o Facebook ou Twitter, em vez de abrir a caixa de diálogo. Se fosse esse o caso, eu poderia criar minha própria caixa de diálogo e, quando clicarem em "Facebook", criar uma intenção específica do Facebook e enviá-las para o Facebook. O mesmo com o Twitter.

Ou isso não é possível? As APIs do Facebook e Twitter são a única maneira?

Kyle Clegg
fonte
Possível duplicado: [custom-filtrando-de-intenção-chooser baseada-on-instalado-android-nome do pacote-] [1] [1]: stackoverflow.com/questions/5734678/...
Asaf Pinhassi
1
Este post de blog parece ser a resposta perfeita: hkdevtips.blogspot.com/2013/02/…
Vitali Olshevski
2
ei amigo ... quando clico no botão enviar, em seguida, abra o compartilhamento de diálogo e a lista de diálogo de compartilhamento é "gmail, email, zapiya, hookup" etc. mas não mostrando facebook, whatsapp, messanger facebook, hangouts caminhada ... como posso mostrar o seu ??
GB_Bhayani
como não mostrar o seletor quando há apenas um item / opção de ação intencional no android 6.0? o problema não mostra com menos do que o Android 6.0
ZYS

Respostas:

324

Que eu saiba, o StackOverflow tem muitas pessoas fazendo essa pergunta de várias maneiras, mas ninguém a respondeu completamente ainda.

Minhas especificações pediam que o usuário pudesse escolher email, twitter, facebook ou SMS, com texto personalizado para cada um. Aqui está como eu consegui isso:

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

Encontrei algumas dicas de como fazer isso em vários lugares, mas não vi tudo em um lugar em nenhum outro lugar.

Observe que esse método também oculta todas as opções tolas que eu não quero, como compartilhar por wifi e bluetooth.

Espero que isso ajude alguém.

Edit: Em um comentário, fui convidado a explicar o que esse código está fazendo. Basicamente, ele cria uma ACTION_SENDintenção SOMENTE para o cliente de email nativo e, em seguida, coloca outras intenções no seletor. Tornar a intenção original específica de e-mail se livra de todo o lixo extra, como wi-fi e bluetooth, então pego as outras intenções que eu quero de um ACTION_SENDtipo genérico de texto sem formatação e as ajudo antes de mostrar o seletor.

Quando pego as intenções adicionais, defino o texto personalizado para cada uma.

Edit2: Já faz um tempo desde que eu postei isso, e as coisas mudaram um pouco. Se você vir o gmail duas vezes na lista de opções, tente remover o tratamento especial para "android.gm", conforme sugerido em um comentário de @h_k abaixo.

Como essa resposta é a fonte de quase todos os meus pontos de reputação no stackoverflow, tenho que pelo menos tentar mantê-la atualizada.

dacoinminster
fonte
1
Estou usando esse código, mas de alguma forma o evernote está entrando na lista. Quando eu checo os nomes dos pacotes, é com.evernote, então não sei por que isso está acontecendo.
precisa
1
@ user2249287 Sugiro que você percorra o código até ver o aplicativo de mensagens que está sendo ignorado e, em seguida, observe o nome do pacote para determinar qual sequência de caracteres você precisa adicionar à lista de permissões desse aplicativo para aparecer.
precisa saber é o seguinte
1
@Gilbou Hi! Desculpe - já faz muito tempo desde que olhei para este código. . . Pelo que me lembro, o comando setPackage escolhe a única intenção à qual você anexará todo o resto. Para incluir ou excluir várias outras intenções, recomendo percorrer o código e examinar os nomes dos pacotes.
dacoinminster
2
Para filtrar APENAS os aplicativos de e-mail que o usuário possui, você pode usar a segunda resposta desta pergunta: stackoverflow.com/questions/8701634/send-email-intent . Ele não requer o uso de um tipo de dado de mensagem / rfc822 que outros aplicativos, como o EverNote, neste caso, também usam.
mpellegr
2
@dacoinminster, seu código foi incrível por me permitir definir um texto diferente para aplicativos como Twitter e Whatsapp. Para remover o gmail duplicado, tirei "android.gm" da equação. Ainda recebo o gmail e o aplicativo de email incorporado na lista de seleções, e o assunto e o texto ainda estão intactos.
h_k
26

Se você deseja uma opção personalizada, não deve confiar na caixa de diálogo padrão fornecida pelo android para esta ação.

O que você precisa fazer é lançar o seu próprio. Você precisará consultar o PackageManager no qual os pacotes lidam com a ação necessária e, com base na resposta, aplicar filtragem e texto personalizado.

Especificamente, dê uma olhada no método queryIntentActivities da classe PackageManager . Você cria a intenção que iniciaria a caixa de diálogo padrão (a intenção ACTION_SEND), a passa para esse método e você receberá uma lista de objetos que contêm informações sobre as atividades que podem lidar com essa intenção. Usando isso, você pode escolher os que deseja.

Depois de criar sua lista de pacotes que você deseja apresentar, você precisa criar sua própria caixa de diálogo de lista (de preferência uma atividade com o tema da caixa de diálogo) que exibirá essa lista.

Uma coisa a ser observada, porém, é que é muito difícil fazer com que a caixa de diálogo personalizada pareça a padrão. O problema é que o tema usado nessa caixa de diálogo é um tema interno e não pode ser usado pelo seu aplicativo. Você pode tentar torná-lo o mais parecido com o nativo que desejar ou optar por uma aparência totalmente personalizada (muitos aplicativos fazem isso como o aplicativo de galeria etc.)

Savvas Dalkitsis
fonte
1
Marcar esta resposta como correta, pois ela responde mais de perto à pergunta original, mesmo que eu tenha acabado seguindo um caminho diferente (veja minha resposta). Obrigado.
Kyle Clegg
22

Experimente este para compartilhar apenas três aplicativos - 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
fonte
este código funciona perfeitamente se você está tentando compartilhar com aplicações específicas
Orcun Sevsay
22

Encontrei uma solução que funciona para mim olhando aqui (veja o terceiro comentário na primeira resposta). Esse código procura um cliente válido do twitter e o usa para postar o tweet. Nota: Ele não fornece uma intenção com os vários clientes do Twitter e permite que você escolha.

Compartilhe usando o twitter:

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

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

O Facebook será semelhante ao uso de " com.facebook.katana ", embora você ainda não possa definir o texto da mensagem (obsoleto em julho de 2011).

Fonte do código: intenção de abrir o cliente do twitter no Android

Kyle Clegg
fonte
4
Não gosto dessa resposta porque ela depende de saber os nomes dos pacotes de todos os aplicativos do twitter. Para uma outra maneira ver stackoverflow.com/questions/6827407/...
Ed Burnette
Concordo com você, embora a resposta à qual você se vinculou tenha um problema semelhante. Eu nunca gosto de confiar em comparações de strings, especialmente quando não tenho controle ou garanto que o string não será alterado.
Kyle Clegg
11

Graças a @dacoinminster. Eu faço algumas modificações em sua resposta, incluindo nomes de pacotes dos aplicativos populares e classificação desses aplicativos.

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

Você pode tentar o código abaixo, ele funciona perfeitamente.

Aqui, compartilhamos com alguns aplicativos específicos, como Facebook, Messenger, Twitter, Google Plus e 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
fonte
qual é o motivo de "if (name.contains (" com.twitter.android.DMActivity ")) {continue;}?
isJulian00
8

Esta solução mostra uma lista de aplicativos em uma caixa de diálogo ListView que se assemelha ao seletor:

captura de tela

Cabe a você:

  1. obter a lista de pacotes de aplicativos relevantes
  2. dado um nome de pacote, chame a intenção relevante

A classe do 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;
    }

}

e seu 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
fonte
4

A maneira mais limpa é copiar as seguintes classes: ShareActionProvider, ActivityChooserView, ActivityChooserModel. Adicione a capacidade de filtrar as intenções no ActivityChooserModel e os métodos de suporte apropriados no ShareActionProvider. Criei as classes necessárias, você pode copiá-las em seu projeto ( https://gist.github.com/saulpower/10557956 ). Isso não apenas adiciona a capacidade de filtrar os aplicativos com os quais você deseja compartilhar (se você souber o nome do pacote), mas também de desativar o histórico.

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
fonte
como adicionar o Google + e outras opção que contêm aplicações remaing
Sunishtha Singh
3

Melhorei a resposta @dacoinminster e este é o resultado com um exemplo para compartilhar seu aplicativo:

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

fonte
3

Eu tive o mesmo problema e esta solução aceita não me ajudou, se alguém tiver o mesmo problema, você pode usar meu snippet 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
fonte
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
fonte
0

Tão simples e conciso. Graças ao desenvolvedor de código aberto, cketti por compartilhar esta solução:

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
}

E este é o link para sua essência.

user10496632
fonte