I want to enable the user of my android app to post some data on fb,twitter and email it to someone as well. I am using Intent.ACTION_SEND for this. I can add the email subject and add test as Intent.EXTRA_TEXT. But I want different texts to be sent to dirrerent applications.
Like the text to be sent to twitter will be short, the text to be sent to facebook will have a link and a shot description, and the on ein email have all the content.
How can I achieve such a functionality?
At most I can let facebook and twitter take the same text but different from what it is in email.
First, create an Intent representing what you want to potentially e-mail, post twitter, etc. Put some good default values in the Intent.EXTRA_TEXT and the subject. Then call, Intent.createChooser() with your intent. This method will return an Intent representing which Activity the user selected. Now, here's where we add the customization you want. Examine the Intent that is returned like so:
Intent intentYouWantToSend = new Intent(Intent.ACTION_SEND);
intentYouWantToSend.putExtra(Intent.EXTRA_TEXT, "Good default text");
List<ResolveInfo> viableIntents = getPackageManager().queryIntentActivities(
intentYouWantToSend, PackageManager.MATCH_DEFAULT_ONLY);
//Here you'll have to insert code to have the user select from the list of
//resolve info you just received.
//Once you've determined what intent the user wants, store it in selectedIntent
//This details of this is left as an exercise for the implementer. but should be fairly
//trivial
if(isTwitterIntent(selectedIntent)){
selectedIntent.putExtra(Intent.EXTRA_TEXT, "Different text for twitter");
}
else if(isFacebookIntent(selectedIntent)){
selectedIntent.putExtra(Intent.EXTRA_TEXT, "Different text for facebook");
}
startActivity(selectedIntent);
By examining the Intent that is returned by Intent.createChooser, we can determine how we need to modify it before launching it. You'll have to implement the isTwiterIntent and isFacebookIntent function yourself though. I imagine this will be relatively easy though, as you probably just have to examine the context of the Intent. I'll do a little more research and see if I can't find an exact solution for determining if an Intent is for Twitter or Facebook, or whatever and try to give you a more complete answer.
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
List<ResolveInfo> activities = getPackageManager().queryIntentActivities(sharingIntent, 0);
By this code you get list of applications that support Intent.ACTION_SEND action.
After that u can built a Alert Dialog to display those applications.
then on click listener of the particular application you can make your changes as given code
public void onClick(DialogInterface dialog, int which)
{
ResolveInfo info = (ResolveInfo) adapter.getItem(which);
if(info.activityInfo.packageName.contains("facebook"))
{
shareToFacebook();
}
else {
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setClassName(info.activityInfo.packageName, info.activityInfo.name);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "hello");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "intent");
startActivity(sharingIntent);
}
}
Related
ShareActionProvider provides share for every compatible app on the device. I would like to specify which apps I want to allow sharing, like only twitter and gmail for example.
How would I do this?
Google don't recommend that you share to specific apps as there are various different Twitter clients - it's better to just let people chose where they want to share it.
However, the following code will send the message "hello twitter" to twitter on a button press.
String message = "hello Twitter";
try {
//try to open the official twitter app
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(
android.content.Intent.EXTRA_SUBJECT, "Subject");
sharingIntent.putExtra(Intent.EXTRA_TEXT, message);
sharingIntent.setPackage("com.twitter.android");
startActivity(sharingIntent);
} catch (Exception e) {
//fallback on opening an internet browser
Log.e("Danielle", "exception=" + e.toString());
Intent i = new Intent();
i.putExtra(Intent.EXTRA_TEXT, message);
i.setAction(Intent.ACTION_VIEW);
i.setData(Uri
.parse("https://mobile.twitter.com/compose/tweet"));
startActivity(i);
}
Hope that helps.
If you are ok with just using a popup, the answer by dacoinminster in this question How to filter specific apps for ACTION_SEND intent (and set a different text for each app) will do it.
But if you specifically want it to be an actionprovider dropdown, I have not find this solution either.
I use intent and Action.SEND for sharing my custom message on social networks like WhatsApp , twitter, Facebook and GMail. Everything is ok on Gmail and other applications except Facebook! How can I customize my code to share something on Facebook as well? I do share on Facebook using Facebook SDK with no problem, but I want to do it using an intent.
this is what I use:
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, knowTitle+"Read the full article via MomsApp by EnfaMama A+ at http://meadjohnsonasia.com.my/mobileapp");
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "I just read "+knowTitle);
sendIntent.setType("*/*");
startActivity(Intent.createChooser(sendIntent, "Share Your Favorite Article"));
What I did was actually to intercept the chosen target of the intenthandlers, you can do that by using your actionprovider. Let's say you created an item that with an onclick starts the intent. In order to do that, you can instantiate an actionprovider to do so. This actionprovider can have a setOnShareTargetSelectedListener to intercept any intents that you want to handle differently (or not at all ^^). See the code below for how to configure your actionprovider.
actionProvider.setShareIntent(createShareIntent());
actionProvider.setOnShareTargetSelectedListener(new OnShareTargetSelectedListener(){
#Override
public boolean onShareTargetSelected(ShareActionProvider source,
Intent intent) {
if ("com.facebook.katana".equals(intent.getComponent().getPackageName()) && mfacebooksharer != null) {
mfacebooksharer.shareStatus(subject, text);
return true;
}
return false;
}
});
Whenever facebook is chosen, I use my mfacebooksharer to handle the intent and follow the facebook API.
Ofcourse, that actionrpovider needs to have an intent. (Just like you wanted to work with an intent). I use the method below to create the intent.
private Intent createShareIntent() {
intentsetter.setIntentleave(true);
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, text);
return shareIntent;
}
As per the Facebook's Platform Policies, you cannot pre-fill the share dialog using
Intent.EXTRA_TEXT. It is usually thought to be a bug, but as per a Bug Report filed here and also, here, Facebook clearly mentions that this is not the case (it's not a bug).
You can read more about their Platform Policies specifically, Platform Policy IV.2
Quote from Platform Policy IV.2:
You must not pre-fill any of the fields associated with the following
products, unless the user manually generated the content earlier in
the workflow: Stream stories (user_message parameter for
Facebook.streamPublish and FB.Connect.streamPublish, and message
parameter for stream.publish), Photos (caption), Videos (description),
Notes (title and content), Links (comment), and Jabber/XMPP.
These fields are intended for users to express themselves. Pre-filling
these fields erodes the authenticity of the user voice.
The only way you can share stories from your App is by integrating the Facebook SDK, which as per your post, you are already able to successfully. That is the only option available (unfortunately).
Using Intent in Android, you can share only a link without text:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "http://www.google.ca");
startActivity(Intent.createChooser(intent, "Share with"));
It'll work. If you want to share text and link , you have to use the Facebook SDK for Android: https://github.com/facebook/facebook-android-sdk
So I would like to do something like:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, Uri.parse(myMessageAsImage));
intent.putExtra(Intent.EXTRA_TEXT, "My Message");
intent.setType("text/plain"); // or intent.setType("image/<imageType>");
However the documentation for ACTION_SEND doesn't seem to make this seem possible. Is there an agreed upon way to do this?
I don't know what you mean by 'common way' but I think you should set the type to intent.setType("image/*");.
EDIT:
How you send data with intent depends on the availability of apps that filter your particular action. Apps that handle ACTION_SEND may not handle ACTION_SEND_MULTIPLE. Clicking Share on HTC Gallery produces a list of applications that handle image, single or multiple. If you choose Mail then you can select multiple images. But if you choose Facebook or Peep then you can only select one image. This is my simple solution if you want to do the reverse of HTC Gallery, that is: user chooses image(s) first then you show him all compatible apps based on how many he selected.
// assuming uris is a list of Uri
Intent intent = null;
if (uris.size > 1){
intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
} else if (uris.size() == 1) {
intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, uris.get(0));}
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_TEXT, "Some message");
startActivity(Intent.createChooser(intent,"compatible apps:"));
I have an Android app and it supports sending text via other apps. It therefore uses the ACTION_SEND intent and the EXTRA_TEXT field. The chooser presents me with all apps that can handle such an intent. Those are Twitter, Email, ... and Facebook. But when I select Facebook it opens the browser and goes to the following page:
http://m.facebook.com/sharer.php?u=mytext
It shows my text and the submit button. But when I press the submit button nothing happens. The page just loads again.
I think maybe it is only possible to send URLs via the Facebook App. Could that be?
Did anyone manage to send text via ACTION_SEND through the Facebook Android app?
To make the Share work with the facebook app, you only need to have suply at least one link:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "Wonderful search engine http://www.google.fr/");
startActivity(Intent.createChooser(intent, "Share with"));
This will show the correct sharing window but when you click on share, nothing happends (I also tried with the official Twitter App, it does not work).
The only way I found to make the Facebook app sharing work is to share only a link with no text:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "http://www.google.fr/");
startActivity(Intent.createChooser(intent, "Share with"));
It will show the following window and the Share button will work:
Apparently it automatically takes an image and text from the link to populate the share.
If you want to share only text, you will have to use the facebook api: https://github.com/facebook/facebook-android-sdk
06/2013 :
This is a bug from Facebook, not your code
Facebook will NOT fix this bug, they say it is "by design" that they broke the Android share system : https://developers.facebook.com/bugs/332619626816423
use the SDK or share only URL.
Tips: you could cheat a little using the web page title as text for the post.
First you need query Intent to handler sharing option. Then use package name to filter Intent then we will have only one Intent that handler sharing option!
Share via Facebook
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Content to share");
PackageManager pm = v.getContext().getPackageManager();
List<ResolveInfo> activityList = pm.queryIntentActivities(shareIntent, 0);
for (final ResolveInfo app : activityList) {
if ((app.activityInfo.name).contains("facebook")) {
final ActivityInfo activity = app.activityInfo;
final ComponentName name = new ComponentName(activity.applicationInfo.packageName, activity.name);
shareIntent.addCategory(Intent.CATEGORY_LAUNCHER);
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
shareIntent.setComponent(name);
v.getContext().startActivity(shareIntent);
break;
}
}
Bonus - Share via Twitter
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Content to share");
PackageManager pm = v.getContext().getPackageManager();
List<ResolveInfo> activityList = pm.queryIntentActivities(shareIntent, 0);
for (final ResolveInfo app : activityList) {
if ("com.twitter.android.PostActivity".equals(app.activityInfo.name)) {
final ActivityInfo activity = app.activityInfo;
final ComponentName name = new ComponentName(activity.applicationInfo.packageName, activity.name);
shareIntent.addCategory(Intent.CATEGORY_LAUNCHER);
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
shareIntent.setComponent(name);
v.getContext().startActivity(shareIntent);
break;
}
}
And if you want to find how to share via another sharing application, find it there Tép Blog - Advance share via Android
EDITED: with the new release of the official Facebook app for Android (July 14 2011) IT WORKS!!!
OLD: The examples above do not work if the user chooses the Facebook app for sharing, but they do work if the user chooses the Seesmic app to post to Facebook. I guess Seesmic have a better implementation of the Facebook API than Facebook!
So I have a work around, but it assumes you have control over the page you're sharing...
If you format your EXTRA_TEXT like so...
String myText = "Hey!\nThis is a neat pic!";
String extraText = "http://www.example.com/myPicPage.html?extraText=\n\n" + myText;
... then on non-Facebook apps, your text should appear something like this:
http://www.example.com/myPicPage.html?extraText=
Hey!
This is a neat pic!
Now if you update your website such that requests with the extraText query parameter return the contents of extraText in the page's meta data.
<!-- Make sure to sanitize your inputs! e.g. http://xkcd.com/327/ -->
<meta name="title" content="Hey! this is a neat pic!">
Then when Facebook escapes that url to generate the dialog, it'll read the title meta data and embed it into your share dialog.
I realize this is a pretty yuck solution, so take with a grain of salt...
It appears that the Facebook app handles this intent incorrectly. The most reliable way seems to be to use the Facebook API for Android.
The SDK is at this link: http://github.com/facebook/facebook-android-sdk
Under 'usage', there is this:
Display a Facebook dialog.
The SDK supports several WebView html
dialogs for user interactions, such as
creating a wall post. This is intended
to provided quick Facebook
functionality without having to
implement a native Android UI and pass
data to facebook directly though the
APIs.
This seems like the best way to do it -- display a dialog that will post to the wall. The only issue is that they may have to log in first
Check this out : By this we can check activity results also....
// Open all sharing option for user
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, ShortDesc+" from "+BusinessName);
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, ShortDesc+" "+ShareURL);
sharingIntent.putExtra(Intent.EXTRA_TITLE, ShortDesc+" "+ShareURL);
startActivityForResult(Intent.createChooser(sharingIntent, "Share via"),1000);
/**
* Get the result when we share any data to another activity
* */
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case 1000:
if(resultCode == RESULT_OK)
Toast.makeText(getApplicationContext(), "Activity 1 returned OK", Toast.LENGTH_LONG).show();
else
Toast.makeText(getApplicationContext(), "Activity 1 returned NOT OK", Toast.LENGTH_LONG).show();
break;
case 1002:
if(resultCode == RESULT_OK)
Toast.makeText(getApplicationContext(), "Activity 2 returned OK", Toast.LENGTH_LONG).show();
break;
}// end switch
}// end onActivityResult
ShareDialog shareDialog = new ShareDialog(this);
if(ShareDialog.canShow(ShareLinkContent.class)) {
ShareLinkContent linkContent = new ShareLinkContent.Builder().setContentTitle(strTitle).setContentDescription(strDescription)
.setContentUrl(Uri.parse(strNewsHtmlUrl))
.build();
shareDialog.show(linkContent);
}
It appears that it's a bug in the Facebook app that was reported in April 2011 and has still yet to be fixed by the Android Facebook developers.
The only work around for the moment is to use their SDK.
if you want to show text put # at the begging of the message you want it will share it as Hashtag
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
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:
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):
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
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.
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.
These answers are all overly complex.
If you just do a normal url Intent that does to Twitter.com, you'll get this screen:
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);
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...
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.
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));
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
}