如何过滤 ACTION_SEND 意图的特定应用程序(并为每个应用程序设置不同的文本)

How to filter specific apps for ACTION_SEND intent (and set a different text for each app)(如何过滤 ACTION_SEND 意图的特定应用程序(并为每个应用程序设置不同的文本))

本文介绍了如何过滤 ACTION_SEND 意图的特定应用程序(并为每个应用程序设置不同的文本)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在使用 ACTION_SEND Intent 时过滤掉特定的应用程序? 已通过各种方式提出了这个问题,但我无法根据给出的答案收集解决方案.希望有人可以提供帮助.我想提供在应用程序内共享的能力.关注 Android Dev Alexander Lucas'建议,我更愿意使用意图而不是使用 Facebook/Twitter API.

How can you filter out specific apps when using the ACTION_SEND intent? This question has been asked in various ways, but I haven't been able to gather a solution based on the answers given. Hopefully someone can help. I would like to provide the ability to share within an app. Following Android Dev Alexander Lucas' advice, I'd prefer to do it using intents and not using the Facebook/Twitter APIs.

使用 ACTION_SEND 意图进行分享很棒,但 问题是 (1) 我不希望所有分享选项都在那里,我宁愿将其限制为 FB、Twitter 和电子邮件,以及 (2) 我不想与每个分享应用分享相同的内容.例如,在我的 twitter 分享中,我将包含一些提及和主题标签,将其限制为 140 个字符或更少,而 facebook 分享将包含一个链接和一张特色图片.

Sharing using the ACTION_SEND intent is great, but the problem is (1) I don't want every sharing option there, I'd rather limit it to FB, Twitter, and Email, and (2) I don't want to share the same thing to each sharing app. For example, in my twitter share I'm going to include some mentions and hashtags limited it to 140 chars or less, while the facebook share is going to include a link and a feature image.

是否可以限制 ACTION_SEND(分享)意图的选项?我已经看到了一些关于使用 PackageManager 和 queryIntentActivities 的信息,但无法弄清楚 PackageManager 和 ACTION_SEND 意图之间的联系.

Is it possible to limit the options for ACTION_SEND (share) intent? I've seen something about using PackageManager and queryIntentActivities, but haven't been able to figure out the connection between the PackageManager and the ACTION_SEND intent.

如果我可以使用 ACTION_SEND 意图直接转到 facebook 或 twitter 而不是弹出对话框,我的问题也可以解决,而不是过滤共享应用程序.如果是这种情况,那么我可以创建自己的对话框,当他们单击Facebook"时,创建一个特定于 Facebook 的意图,然后将它们一直发送到 Facebook.与 Twitter 相同.

Rather than filter the sharing apps, my problem could also be solved if I could use the ACTION_SEND intent to go directly to facebook or twitter rather than popping up the dialog. If that were the case then I could create my own dialog and when they click "Facebook" create a Facebook-specific intent and just send them all the way to Facebook. Same with Twitter.

或者这不可能吗?Facebook 和 Twitter API 是唯一的方法吗?

OR is it not possible? Are the Facebook and Twitter APIs the only way?

推荐答案

据我所知,StackOverflow 有很多人以各种方式提出这个问题,但还没有人完整回答.

To my knowledge, StackOverflow has lots of people asking this question in various ways, but nobody has answered it completely yet.

我的规范要求用​​户能够选择电子邮件、推特、脸书或短信,并为每个人选择自定义文本.我是这样实现的:

My spec called for the user to be able to choose email, twitter, facebook, or SMS, with custom text for each one. Here is how I accomplished that:

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

我在不同的地方找到了一些如何做到这一点,但我还没有在其他任何地方看到所有这些.

I found bits of how to do this in various places, but I haven't seen all of it in one place anywhere else.

请注意,此方法还隐藏了我不想要的所有愚蠢选项,例如通过 wifi 和蓝牙共享.

Note that this method also hides all the silly options that I don't want, like sharing over wifi and bluetooth.

希望这对某人有所帮助.

Hope this helps someone.

在评论中,我被要求解释这段代码在做什么.基本上,它只为本地电子邮件客户端创建一个 ACTION_SEND 意图,然后将其他意图附加到选择器上.使原始意图电子邮件特定于摆脱所有额外的垃圾,如 wifi 和蓝牙,然后我从纯文本类型的通用 ACTION_SEND 中获取我想要的其他意图,并在显示之前添加它们选择器.

In a comment, I was asked to explain what this code is doing. Basically, it's creating an ACTION_SEND intent for the native email client ONLY, then tacking other intents onto the chooser. Making the original intent email-specific gets rid of all the extra junk like wifi and bluetooth, then I grab the other intents I want from a generic ACTION_SEND of type plain-text, and tack them on before showing the chooser.

当我获取其他意图时,我为每个意图设置了自定义文本.

When I grab the additional intents, I set custom text for each one.

Edit2:自从我发布此内容以来已经有一段时间了,事情发生了一些变化.如果您在选项列表中看到 gmail 两次,请尝试按照下面@h_k 的评论中的建议删除android.gm"的特殊处理.

It's been awhile since I posted this, and things have changed a bit. If you are seeing gmail twice in the list of options, try removing the special handling for "android.gm" as suggested in a comment by @h_k below.

由于这个答案几乎是我所有的 stackoverflow 信誉积分的来源,我必须至少尝试使其保持最新状态.

Since this one answer is the source of nearly all my stackoverflow reputation points, I have to at least try to keep it up to date.

这篇关于如何过滤 ACTION_SEND 意图的特定应用程序(并为每个应用程序设置不同的文本)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:如何过滤 ACTION_SEND 意图的特定应用程序(并为每个应用程序设置不同的文本)

基础教程推荐