安卓Twitter应用程序的意图(Intent)

62

是否可以使用 intent.createChooser 显示一个应用程序列表,其中仅显示我在手机上的 Twitter 应用程序(例如 htc peep (htc hero) 或 twitdroid)?我尝试过使用 intent.settype("application/twitter") 但它无法找到任何 Twitter 应用程序,只显示我的邮件应用程序。

谢谢,

Wouter


Twitter通过Fabric创建了一个库。寻找此解决方案的人现在可以在这里找到它。http://docs.fabric.io/android/twitter/compose-tweets.html#set-up-kit 希望这可以帮助到你。 - Kennedy Nyaga
9个回答

84

我发布这篇文章是因为我还没有看到一个完全符合我的需求的解决方案。

主要是启动官方Twitter应用程序,如果未安装,则会弹出"使用以下操作完成"对话框 (像这样) 或直接启动Web浏览器。

有关twitter.com URL中不同参数的列表,请参见Tweet Button文档。记得对参数值进行URL编码。(此代码专门用于发推链接;如果您不想要,只需省略url参数即可。)

// Create intent using ACTION_VIEW and a normal Twitter url:
String tweetUrl = String.format("https://twitter.com/intent/tweet?text=%s&url=%s",
        urlEncode("Tweet text"), 
        urlEncode("https://www.google.fi/"));
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(tweetUrl));

// Narrow down to official Twitter app, if available:
List<ResolveInfo> matches = getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo info : matches) {
    if (info.activityInfo.packageName.toLowerCase().startsWith("com.twitter")) {
        intent.setPackage(info.activityInfo.packageName);
    }
}

startActivity(intent);

如果你有一个小实用程序,比如 "StringUtils",那么URL编码会更加简洁。

public static String urlEncode(String s) {
    try {
        return URLEncoder.encode(s, "UTF-8");
    }
    catch (UnsupportedEncodingException e) {
        Log.wtf(TAG, "UTF-8 should always be supported", e);
        throw new RuntimeException("URLEncoder.encode() failed for " + s);
    }
}

例如,在我的Nexus 7设备上,直接打开官方Twitter应用程序

图片描述

如果未安装官方Twitter应用程序,并且用户选择Chrome或它自动打开(作为唯一可以处理该意图的应用程序):

图片描述


2
这个答案最棒的部分是选择器似乎还包括已安装的流行第三方 Twitter 客户端。 - Peter
3
非常感谢你,Jonik!这应该是被采纳的答案(即使是Twitter官方的答案)。billynomates的回答也不错,而且更简单。但是你所说的正是我们所需要的(直接去Twitter或者返回其他客户端),并且可能是大多数人想要做的。如果我可以的话,我会投两票的。 :) - Ferran Maylinch
好的回答!非常有效。您知道是否可以使用此URL填充来包括例如图像的URL到推文中,或者如果安装了Twitter应用程序,则将此信息作为Intent Extra数据发送吗? - Matti Vilola
1
@Matti:抱歉,我不知道那个。试一下看看是否有效 :) - Jonik
1
非常简短、简单而又强大的解决方案!非常感谢! - user2424370
显示剩余4条评论

40
之前发布的解决方案可以让您在第一个Twitter应用程序中直接发布。如果有多个Twitter应用程序,您可以自定义Intent.createChooser以显示您想要的Intents。诀窍是将EXTRA_INITIAL_INTENTS添加到从createChoose生成的默认列表中,并从列表中删除其他Intents。
请看这个示例,我创建了一个仅显示我的电子邮件应用程序的选择器。在我的情况下,出现了三个邮件应用程序:Gmail、YahooMail和默认邮件应用程序。
private void share(String nameApp, String imagePath) {
    List<Intent> targetedShareIntents = new ArrayList<Intent>();
    Intent share = new Intent(android.content.Intent.ACTION_SEND);
    share.setType("image/jpeg");
    List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(share, 0);
    if (!resInfo.isEmpty()){
        for (ResolveInfo info : resInfo) {
            Intent targetedShare = new Intent(android.content.Intent.ACTION_SEND);
            targetedShare.setType("image/jpeg"); // put here your mime type

            if (info.activityInfo.packageName.toLowerCase().contains(nameApp) || 
                    info.activityInfo.name.toLowerCase().contains(nameApp)) {
                targetedShare.putExtra(Intent.EXTRA_TEXT,     "My body of post/email");
                targetedShare.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(imagePath)) );
                targetedShare.setPackage(info.activityInfo.packageName);
                targetedShareIntents.add(targetedShare);
            }
        }

        Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Select app to share");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
        startActivity(chooserIntent);
    }
}

你可以这样运行:share("twi", "/sdcard/dcim/Camera/photo.jpg");

这是基于此帖子的:Custom filtering of intent chooser based on installed Android package name


2
只是一个细节:"twi" 可以获取 Twitter 和 Twicca,但会错过许多其他客户端,例如 TweetCaster、HootSuite 和 Plume。 - Pierre-Luc Paour
先生,请帮忙。我使用这段代码进行图像和文本共享,但是当我调用此方法时,它会崩溃。请帮帮我,我该怎么办?请帮忙。 - Rishi Gautam
@RishiGautam请发布您的异常堆栈跟踪。 - Derzu
@RishiGautam,你的问题是IndexOutOfBoundsException,你正在尝试访问大小为零的数组的元素零。在这一行:com.example.creeper.Camera.share(Camera.java:770)。这一行上是什么? - Derzu
太棒了..运行良好.. :-) - Sid
显示剩余7条评论

34

这个问题有点旧,但是因为我刚碰到了类似的问题,所以它可能仍然对其他人感兴趣。首先,如Peter所提到的,创建你的意图:

Intent tweetIntent = new Intent(Intent.ACTION_SEND);
tweetIntent.putExtra(Intent.EXTRA_TEXT, "Test; please ignore");
tweetIntent.setType("application/twitter");

"application/twitter"实际上是一个已知的内容类型,可以在这里找到相关信息。当你尝试使用这个意图启动一个活动时,它会显示所有不是真正的Twitter客户端但想要一份“大餐”的应用程序。就像一些“为什么你甚至要那样做?”这样的答案中已经提到的那样,一些用户可能会觉得这很有用。另一方面,如果我在我的应用程序中有一个按钮,上面写着“发推文!”,那么用户非常希望能弹出Twitter客户端。

这意味着我们需要过滤适当的活动,而不仅仅是启动所有活动:

PackageManager pm = getPackageManager();
List<ResolveInfo> lract 
= pm.queryIntentActivities(tweetIntent,
    PackageManager.MATCH_DEFAULT_ONLY);

boolean resolved = false;

for(ResolveInfo ri: lract)
{
    if(ri.activityInfo.name.endsWith(".SendTweet"))
    {
        tweetIntent.setClassName(ri.activityInfo.packageName,
                        ri.activityInfo.name);
        resolved = true;
        break;
    }
}
你需要尝试一下不同的提供者,但如果名称以“.SendTweet”结尾,那么你就比较安全了(这是Twidroyd中的活动名称)。你还可以检查调试器中要使用的包名,并相应地调整字符串比较(例如,Twidroyd使用“com.twidroid.*”)。
在这个简单的例子中,我们只选择找到的第一个匹配活动。这将直接启动Twitter客户端,而不需要用户做出任何选择。如果没有合适的Twitter客户端,我们将恢复到标准的活动选择器:
startActivity(resolved ? tweetIntent :
    Intent.createChooser(tweetIntent, "Choose one"));

您可以扩展代码并考虑存在多个 Twitter 客户端的情况,当您可能希望从找到的所有活动名称中创建自己的选择对话框时。


5
"application/twitter" 并不是官方的 MIME 类型,因此仅被 twitdroid 支持。至于 sendTweet 方法名,我认为它更为严格限制。 - rds
1
最终我采用了你的想法和rds博客链接的混合,但如果我找不到适合发推文的应用程序,我会使用他们的URL来分享评论(http://twitter.com/home?status=Hi+There)。 - Maragues
先生,请帮帮我,我试图在 Twitter 上发送图片,但没有成功,请告诉我如何发送图片。如果您有示例代码,请与我分享。 - Rishi Gautam
我认为它甚至没有显示Twitter...我使用了Jonik的答案。 - Ferran Maylinch

23

完全有可能你的用户现在和将来只想要发布推文。

我认为更有可能的情况是,你的用户想要向别人发送信息,Twitter 只是其中一种可能。但是,他们也可能想要发送短信或电子邮件等。

如果是这样的话,请使用 ACTION_SEND,具体说明可以参考 这里。值得一提的是,Twidroid 支持 ACTION_SEND,因此它将出现在可用交付机制的列表中。


7
“ACTION_SEND”指令过于含糊不清,可以使用Gmail和Dropbox。我建议您基于已知的包名来过滤列表,以获得更精确的结果。参考链接:http://regis.decamps.info/blog/2011/06/intent-to-open-twitter-client-on-android/ - rds
6
@rds:ACTION_SEND并不是“太模糊了”。用户在许多其他地方也想要分享东西--正如我在答案中所写的那样,理想情况下,应用程序不应仅限制用户通过Twitter分享。而你的过滤器“太脆弱”和“太危险”,因为它依赖于来自一小部分Twitter客户端的未记录信息。如果你只想分享到Twitter,请使用Twitter客户端API。 - CommonsWare
23
一些应用程序希望限制在 Twitter 上发布,这就是此处所要求的。使用 Twitter API 会出现以下情况:a-重新发明轮子 b-重复了HTC / Samsung / Twitter 已经提供的内容 c-过于复杂(身份验证、失败后重新发布、缩短网址等)。 - rds
1
@CommonsWare 我同意问题比较含糊,但您并没有真正回答它。在我的情况下,我想为特定用户打开一个Twitter页面,并有使用应用程序或浏览器作为备选方案的选项,您的回答只涵盖了提问者希望通过Twitter发送信息,而不是像我一样检索信息的假设。 - Hamid
1
是的,但用户会对我的应用程序做出不好的评价,而不是对Facebook做出评价。 对于他们来说,这看起来像是我的应用程序的错误。 还有许多集成SDK的应用程序,所以他们很难知道这是Facebook的问题。 - User
显示剩余6条评论

17

这些答案都过于复杂。

如果您只是执行一个普通的URL意图,然后跳转到Twitter.com,您将会看到这个屏幕:

enter image description here

如果您没有安装Twitter应用程序,则可以选择访问该网站。

String url = "https://twitter.com/intent/tweet?source=webclient&text=TWEET+THIS!";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);

这对我来说不起作用。我收到了提示,但只有Chrome和Firefox显示,尽管我已经安装了Twitter。事实证明,它不能与 https://mobile.twitter.com/... 一起使用,必须是 https://twitter.com/...。此外,这对于hashtags也不起作用。 - Kyle Falconer

9

2
请查看http://regis.decamps.info/blog/2011/06/intent-to-open-twitter-client-on-android/,以获取此想法的实现。 - rds
感谢指出我的博客。我的实现中存在一个问题,当Facebook应用程序在另一个活动的前台时,它无法正确打开帖子意图。 - Rafael Sanches
@rds,您好,能帮我一下吗?我试图发布图片但没有成功,请帮帮我。谢谢。 - Rishi Gautam
对于那些想要启动官方Twitter应用程序的人,以下是如何轻松可靠地完成 - Jonik

4

不行。意图类型是类似于image/pngapplication/pdf,也就是文件类型。而使用createChooser,你基本上是在询问哪些应用程序可以打开此文件类型。

现在,没有可以打开的application/twitter文件,所以那样做行不通。我也不知道你还有什么其他方法可以实现你想要的。


那我必须使用类型为(text/*)的方式,这样它就会显示所有可能性,包括Twitter?或者我必须为我的应用程序编写自己的Twitter状态更新 :) - wouter88
这确实不是官方的 MIME 类型。因此,它仅由 twitdroid 支持。 - rds
先生,请帮我在 Twitter 上分享这张图片。我尝试了很多代码,但都没有成功。请您帮帮我。谢谢! - Rishi Gautam
先生,我想在 Twitter 上发布图片,请问如何在 Twitter 墙上发布图片?如果您有示例代码,请与我分享。谢谢。 - Rishi Gautam

3

来自http://twidroid.com/plugins/

Twidroid的ACTION_SEND意图

Intent sendIntent = new Intent(Intent.ACTION_SEND); 
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is a sample message via Public Intent"); 
sendIntent.setType("application/twitter");   
startActivity(Intent.createChooser(sendIntent, null)); 

2
这不是官方的 MIME 类型。因此,它仅由 twitdroid 支持。 - rds

3

我使用了“billynomates”的答案,并且通过使用“URLEncoder.encode(,“UTF-8”)”函数能够使用哈希标签。 哈希标签正常显示。

String originalMessage = "some message #MESSAGE";

String originalMessageEscaped = null;
try {
   originalMessageEscaped = String.format(
    "https://twitter.com/intent/tweet?source=webclient&text=%s",
    URLEncoder.encode(originalMessage, "UTF-8"));
} catch (UnsupportedEncodingException e) {
   e.printStackTrace();
}

if(originalMessageEscaped != null) {
   Intent i = new Intent(Intent.ACTION_VIEW);
   i.setData(Uri.parse(originalMessageEscaped));
   startActivity(i);
}
else {
   // Some Error
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接