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

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

问题描述

如何在使用 ACTION_SEND 意图时过滤掉特定的应用程序? 已经以各种方式提出了这个问题,但我无法根据给出的答案收集解决方案.希望有人可以提供帮助.我想提供在应用程序内共享的功能.关注 Android 开发者亚历山大卢卡斯建议,我更愿意使用意图而不是使用 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.与推特相同.

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 意图过滤特定应用(并为每个应用设置不同的文本)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆