62

Is it possible to show a list of applications (with intent.createChooser) that only show me my twitter apps on my phone (so htc peep (htc hero) or twitdroid). I have tried it with intent.settype("application/twitter") but it doesnt find any apps for twitter and only shows my mail apps.

Thank you,

Wouter

David Webb
  • 190,537
  • 57
  • 313
  • 299
wouter88
  • 1,294
  • 4
  • 15
  • 19
  • Twitter, through fabric have created a library for this. Persons searching for this solution can now find it here. http://docs.fabric.io/android/twitter/compose-tweets.html#set-up-kit hope this helps. – Kennedy Nyaga Aug 24 '15 at 20:10

9 Answers9

84

I'm posting this because I haven't seen a solution yet that does exactly what I want.

This primarily launches the official Twitter app, or if that is not installed, either brings up a "Complete action using..." dialog (like this) or directly launches a web browser.

For list of different parameters in the twitter.com URL, see the Tweet Button docs. Remember to URL encode the parameter values. (This code is specifically for tweeting a URL; if you don't want that, just leave out the url param.)

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

(URL encoding is cleaner if you have a little utility like this somewhere, e.g. "StringUtils".)

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

For example, on my Nexus 7 device, this directly opens the official Twitter app:

enter image description here

If official Twitter app is not installed and user either selects Chrome or it opens automatically (as the only app which can handle the intent):

enter image description here

nikib3ro
  • 20,366
  • 24
  • 120
  • 181
Jonik
  • 80,077
  • 70
  • 264
  • 372
  • 2
    Best part about this answer is that the chooser also seems to include popular 3rd party Twitter clients if installed – Peter May 09 '14 at 15:30
  • 3
    Thanks a lot, Jonik! This should be the accepted answer (even Twitter official answer). `billynomates`'s answer is also good, and simpler. But what you say is exactly what we needed (go to Twitter directly or fall back to other clients) and probably what most people would like to do. I'd double-vote if I could. :) – Ferran Maylinch Aug 01 '14 at 16:45
  • Good answer! Works great. Do you know if it is possible to use this URL population to include e.g. URL of the image to the tweet or alternatively send this information as Intent Extra data if Twitter app is installed? – Matti Vilola Aug 25 '14 at 17:25
  • 1
    @Matti: Sorry, I don't know about that. Try and see if it works :) – Jonik Aug 26 '14 at 09:07
  • 1
    Very short, simple and powerful solution! Thanks a lot! –  Dec 26 '14 at 06:00
  • I can't share image with Intent.ACTION_VIEW :( – IliaEremin Jan 12 '15 at 10:49
  • @Jonik i want to include image also is there any way – sujith s May 08 '15 at 10:39
  • @sujiths did u find a solution for adding image ? – Muhammad Umar Nov 18 '15 at 04:39
40

The solutions posted before, allow you to post directly on your first twitter app. To show a list of twitters app (if there are more then one), you can custom your Intent.createChooser to show only the Itents you want.

The trick is add EXTRA_INITIAL_INTENTS to the default list, generated from the createChoose, and remove the others Intents from the list.

Look at this sample where I create a chooser that shows only my e-mails apps. In my case appears three mails: Gmail, YahooMail and the default Mail.

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

You can run like that: share("twi", "/sdcard/dcim/Camera/photo.jpg");

This was based on post: Custom filtering of intent chooser based on installed Android package name

Community
  • 1
  • 1
Derzu
  • 7,011
  • 3
  • 57
  • 60
  • 2
    Just a detail: "twi" gets Twitter and Twicca, but misses many other clients such as TweetCaster, HootSuite and Plume. – Pierre-Luc Paour Jan 28 '13 at 14:23
  • @Pierre-LucPaour You are right. The code can be adapted to try to match more than one app partial name. I think there isn't a way to show all (and just) twitter applications without knowing the name or part of the name of these applications. Is there any other way? Is the solution of the alexander-rautenberg works for all twitters apps? – Derzu Jan 29 '13 at 13:40
  • I merely meant to point out to future readers that they do need to inventory the various Twitter clients and their naming rather than blindly using this code. – Pierre-Luc Paour Jan 29 '13 at 20:59
  • sir plz help i use this code for image sharing and text when i call this method ti will crash plz help me how can i do . plz help – Rishi Gautam Mar 23 '13 at 11:58
  • @RishiGautam please post your exception stack trace. – Derzu Mar 23 '13 at 21:10
  • ok sir first of all thanks for reply , sir her is error sir http://pastie.org/private/jweetgy6nru3zercrupf8q – Rishi Gautam Mar 24 '13 at 04:01
  • @RishiGautam your problem is a IndexOutOfBoundsException, you are trying to access the element zero of an array of size zero. At this line: com.example.creeper.Camera.share(Camera.java:770). What is at this line? – Derzu Mar 24 '13 at 21:30
  • sir this my package com.example.creeper.Camera.share(Camera.java:770). where the camera.java class in this package . when i use try catch block the exception come in IndexOutOfBoundsException, in this line Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Select app to share"); – Rishi Gautam Mar 25 '13 at 04:18
  • @RishiGautam This happens when you have zero apps whose packetname matches with the nameApp that you pass as parameter. So if you are passing share("twi", ... probably you don't have the twitter app installed. Which nameApp are you passing as parameter? – Derzu Mar 26 '13 at 20:17
  • This worked for me on Twitter (with image) + on Facebook I was able to get the image shared (not text) – Mahendra Liya Jun 20 '14 at 22:01
  • This will require Twitter app to be installed on the phone. Is there any way that won't need twitter app? – Adil Malik Aug 28 '14 at 14:07
  • Awesome..Worked Well.. :-) – Sid Aug 07 '18 at 09:20
34

This question is a bit older, but since I have just come across a similar problem, it may also still be of interest to others. First, as mentioned by Peter, create your intent:

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

"application/twitter" is in fact a known content type, see here. Now, when you try to start an activity with this intent, it will show all sorts of apps that are not really Twitter clients, but want a piece of the action. As already mentioned in a couple of the "why do you even want to do that?" sort of answers, some users may find that useful. On the other hand, if I have a button in my app that says "Tweet this!", the user would very much expect this to bring up a Twitter client.

Which means that instead of just launching an activity, we need to filter out the ones that are appropriate:

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

You would need to experiment a bit with the different providers, but if the name ends in ".SendTweet" you are pretty safe (this is the activity name in Twidroyd). You can also check your debugger for package names you want to use and adjust the string comparison accordingly (i.e. Twidroyd uses "com.twidroid.*").

In this simple example we just pick the first matching activity that we find. This brings up the Twitter client directly, without the user having to make any choices. If there are no proper Twitter clients, we revert to the standard activity chooser:

startActivity(resolved ? tweetIntent :
    Intent.createChooser(tweetIntent, "Choose one"));

You could expand the code and take into account the case that there is more than one Twitter client, when you may want to create your own chooser dialog from all the activity names you find.

Alexander Rautenberg
  • 2,205
  • 2
  • 22
  • 20
  • 5
    "application/twitter" not an official MIME type. Hence, it is supported only by twitdroid. As for the `sendTweet`method name, I think it's even more restricitve – rds Dec 19 '11 at 16:10
  • 1
    I ended up using your idea mixed with rds's blog link, but if I don't find any application suitable for tweeting, I use their url to share the comment (http://twitter.com/home?status=Hi+There) – Maragues Jan 31 '12 at 18:48
  • sir help me , itry to send the image on twitter but not get success please help me how to send the image . if u have a sample code please share with me – Rishi Gautam Mar 24 '13 at 04:23
  • I think it didn't even display Twitter... I used Jonik's answer. – Ferran Maylinch Aug 01 '14 at 16:48
23

It is entirely possible your users will only ever, now and forever, only want to post to Twitter.

I would think that it is more likely that your users want to send information to people, and Twitter is one possibility. But, they might also want to send a text message, or an email, etc.

In that case, use ACTION_SEND, as described here. Twidroid, notably, supports ACTION_SEND, so it will appear in the list of available delivery mechanisms.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 7
    `ACTION_SEND` is too vague. Gmail and dropbox are eligible. [I suggest you filter](http://regis.decamps.info/blog/2011/06/intent-to-open-twitter-client-on-android/) the list based on known package names. – rds Jun 02 '11 at 10:01
  • 6
    @rds: `ACTION_SEND` is not "too vague". There are lots of other places where users will want to share things -- as I wrote in my answer, ideally, apps do not limit users to sharing only via Twitter. And your filter is "too fragile" and "too dangerous", in that it relies on undocumented information from a tiny list of Twitter clients. If you only want to share to Twitter, use the Twitter client API. – CommonsWare Jun 04 '11 at 13:34
  • 23
    Some applications want to limit to twitter posting, and this is what was asked here. Using the twitter API is a- reinventing the wheel b- a duplicate of what HTC/Samsung/twitter has already provided c- complicated (authentification, repost if fail, tiny url, etc.) – rds Jun 04 '11 at 13:53
  • I agree with rds. I'd prefer to customize the message formatting for the appropriate channel. An email has a subject line, a tweet does not. Because most apps don't bother to filter themselves out appropriately (even with the application/twitter mime type set), manually filtering for known twitter apps seems to be an appropriate workaround. – jasonhudgins Mar 22 '12 at 02:22
  • @jasonhudgins If you set the all appropriate EXTRAS in the intent, then whatever is selected will use only what applies to it. Email clients will use the subject extra, meanwhile a twitter client will only use the text extra and so on. The code example @ rds links to only selects one package name and if a user has a twitter client not in that hard-coded list, the sharing will fail. Also, a chooser is not created but instead the set package immediately launched. What if a user has two clients but prefers one over the other? The preferred one may not be selected, which is not a good UX. – codinguser Jul 14 '12 at 18:44
  • @CommonsWare Is there any way to detect which Sharing media is selected for sharing? Because i want to change subject accordingly. – Paresh Mayani Jul 16 '12 at 05:34
  • 1
    @CommonsWare I agree that the question is vague, but you really aren't answering it. In my case, I want to open a twitter page for a specific user, with the option of using the app, or the browser as a fall back, your answer only covers the assumption that the person asking the questions intends to send information via twitter, as opposed to retrieving it, as is my intention. – Hamid Jul 26 '12 at 13:52
  • @CommonsWare and how to deal with Facebook's bug/"feature" of not prefilling the message? If Facebook will not work properly, you can't use the dialog. – User Mar 04 '13 at 13:22
  • @ixx: 'If Facebook will not work properly, you can't use the dialog" -- the issue with Facebook is between the user and Facebook. If you work for Facebook, fix your "bug". If you do not work for Facebook, it is not your "bug" and not your problem. – CommonsWare Mar 04 '13 at 13:31
  • 1
    Well, yes, but the users will do bad ratings about my app, not about Facebook. For them it looks like an error of my app. And there are also many apps which integrate the SDK, so it's hard for them to know that it's Facebook's fault. – User Mar 04 '13 at 13:56
  • i try this code but no get success please help me hoe to send the image on the twitter in android – Rishi Gautam Mar 23 '13 at 12:02
17

These answers are all overly complex.

If you just do a normal url Intent that does to Twitter.com, you'll get this screen:

enter image description here

which gives you the option of going to the website if you have no Twitter apps installed.

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);
MSpeed
  • 8,153
  • 7
  • 49
  • 61
  • This wasn't working for me. I was getting the prompt but only Chrome and Firefox were showing, even though I have Twitter installed. Turns out, it won't work with the `https://mobile.twitter.com/...`, and must be `https://twitter.com/...` Additionally, This will not work for hashtags. – Kyle Falconer Aug 13 '13 at 18:45
9

Either

  • You start an activity with an Intent with action Intent.ACTION_SEND and the text/plain MIME type. You'll have all applications that support sending text. That should be any twitter client, as well as Gmail, dropbox, etc.
  • Or, you try to look up for the specific action of every client you are aware of, like "com.twitter.android.PostActivity" for the official client. That will point to this client, and that is unlikely to be a complete list.
  • Or, you start with the second point, and fall back on the first...
rds
  • 26,253
  • 19
  • 107
  • 134
  • 2
    See http://regis.decamps.info/blog/2011/06/intent-to-open-twitter-client-on-android/ for an implementation of this idea – rds Jun 02 '11 at 10:02
  • thanks for pointing to my blog. One of the problems with my implementation is when the facebook app is in the foreground in another activity, it won't open the post intent correctly. – Rafael Sanches Feb 28 '12 at 02:07
  • @rds sir csn u help me sir i try to poast the image but not get success plz help me sir – Rishi Gautam Mar 24 '13 at 04:19
  • For those who want to fire up the **official Twitter app**, [here's how to do it easily and reliably](http://stackoverflow.com/a/21186753/56285). – Jonik Jan 17 '14 at 17:31
4

Nope. The intent type is something like image/png or application/pdf, i.e. a file type, and with createChooser you're basically asking which apps can open this file type.

Now, there's no such thing as an application/twitter file that can be opened, so that won't work. I'm not aware of any other way you can achieve what you want either.

Mirko N.
  • 10,537
  • 6
  • 38
  • 37
  • So i will have to use as type (text/*) so it shows me all the posibilities including twitter? Or I have to write my own twitter status update for my app :) – wouter88 Jan 16 '10 at 11:57
  • It's indeed not an official MIME type. Hence, it is supported only by twitdroid – rds Mar 13 '11 at 18:52
  • sir share the image on twitter i try many code not get success plz hel me sir – Rishi Gautam Mar 23 '13 at 12:03
  • sir i try to poast the image on wall of twitter sir please how to post the image on the wall of twitter , if u have a sample code please share with me thank you – Rishi Gautam Mar 24 '13 at 04:21
3

I used "billynomates" answer and was able to use hashtags by using the "URLEncoder.encode(, "UTF-8")" function. The hash tags showed up just fine.

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
}
echappy
  • 533
  • 5
  • 13
3

From http://twidroid.com/plugins/

Twidroid’s ACTION_SEND intent

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)); 
Peter
  • 31
  • 1