Related
My Android app contains links, I want to share this link on Facebook. I used Intent.ACTION_SEND but why
Facebook icon is not shown on Activity Chooser, my code:
Intent sharing = new Intent(Intent.ACTION_SEND);
sharing.setType("text/html");
sharing.putExtra(Intent.EXTRA_SUBJECT, "Check out this video");
sharing.putExtra(Intent.EXTRA_TEXT,
"https://www.youtube.com/watch?v=" + videoUrl);
startActivity(Intent.createChooser(sharing, "What to share?"));
Change
sharing.setType("text/html");
To
sharing.setType("text/plain");
This modification solved this issue here. Hope it will help you!
Also, check this code that I use to share a link using specific apps: http://pastebin.com/JhYzdL4s.
I think you need to set the package for your sharing intent.
For example, if you want to set a Facebook package, you need to do:
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(share, 0);
for (ResolveInfo info : resInfo) {
String packageName = info.activityInfo.packageName;
if(packageName.toLowerCase().contains("facebook")) {
share.setPackage(info.activityInfo.packageName);
}
}
I am trying to post a link on facebook with the native android sharing function. I found out that i can't set the message for the link. But now i want to set the title, message and the url.
I want to set the items in the red square. I already found out I couldnt set the Test, because of the user policies.
Some code:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TITLE, title);
shareIntent.putExtra(Intent.EXTRA_TEXT, title + "\n\n" + contentLink);
shareIntent.setType("text/plain");
return shareIntent;
This is the code I have at this moment, but this doesnt set the items in the red square.
Text Sharing :
Using Android Intent Share for Facebook you can't share pre-populated text. This is blocked by facebook itself due to platform policy. Checkout section 2.3 in the below linl
https://developers.facebook.com/policy
Link Sharing :
You can share a link. Facebook will automatically fetch the link metadata. i.e a image, meta title and meta description.
Image Sharing :
User images can be shared. Which means you can share images stored on your device. You cannot share images from your app directly without saving them. As a hack, you can save the image on device, share and delete the image (if you don't want image to appear in user's gallery).
Use this code to share only link. Facebook will automatically fetch the link metadata. i.e, image, meta title and meta description.
String urlToShare = "--------URL-------";
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, urlToShare);
// See if official Facebook app is found
boolean facebookAppFound = false;
List<ResolveInfo> matches = getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo info : matches)
{
if (info.activityInfo.packageName.toLowerCase().startsWith("com.facebook"))
{
intent.setPackage(info.activityInfo.packageName);
facebookAppFound = true;
break;
}
}
if (!facebookAppFound)
{
String sharerUrl = "https://www.facebook.com/sharer/sharer.php?u=" + urlToShare;
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(sharerUrl));
}
startActivity(intent);
I'm using the following code to tweet something from another app:
try{
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, "It's a Tweet!" + "#MyApp");
intent.setType("text/plain");
final PackageManager pm = getPackageManager();
final List<?> activityList = pm.queryIntentActivities(intent, 0);
int len = activityList.size();
for (int i = 0; i < len; i++) {
final ResolveInfo app = (ResolveInfo) activityList.get(i);
if ("com.twitter.android.PostActivity".equals(app.activityInfo.name)) {
final ActivityInfo activity=app.activityInfo;
final ComponentName x=new ComponentName(activity.applicationInfo.packageName, activity.name);
intent=new Intent(Intent.ACTION_SEND);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
intent.setComponent(x);
intent.putExtra(Intent.EXTRA_TEXT, "blah blah" );
startActivity(intent);
break;
}
}
} catch(final ActivityNotFoundException e) {
Log.i("Twitter intent", "no twitter native", e );
}
The above code works perfectly if the twitter app is installed on the phone but is not open. But if I was using twitter before using the above activity, then I just simply get transferred to the same point where I last left twitter and the text that I wanted to tweet is not posted. What should I do to correct this?
Also, if twitter is not installed on my phone, then nothing happens. On pressing the button that starts the intent above nothing happens but shouldn't I actually be getting the message - no twitter native. What should be done to get the message??
I think you should use setClassName instead of setComponent.
intent.setClassName("com.twitter.android", "com.twitter.android.PostActivity");
But as a helpful side note, There are several options for you to integrate with twitter:
1)Use their API (maybe use a library such as twitter4j), or
2)Find a way to integrate with the Twitter app, like you are doing right now. This is not a good idea because many people use other apps such as Plume, TweetDeck and so on and your app wont work if they dont have twitter installed.
3)you can just open up http://twitter.com/?status= using a simple intent.
This can be done like:
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("http://twitter.com/?status=" + Uri.encode(message)));
startActivity(i);
You can also combine 2 and 3. You can try a few known twitter apps and if they are absent, call the browser.
Also note that it might be possible for method 3 to actually launch an app instead of the browser (or at least give the user a choice between the two), if the app handles the correct intents.
In my opinion, Method 1 is best since it only depends on your app ( well, except for the library) and you don't have to integrate with third party apps that the user may or may not have.
Simple remove Intent.FLAG_ACTIVITY_NEW_TASK for Intent.FLAG_ACTIVITY_CLEAR_TASK, so the task where the twitter is running gets re-started.
Your flags should look like this now:
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Hope this helps, and remember to accept the answer if correct :)
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
}