Need to share text via applications - android

I need to share text from my applications via other social applications.I have got a piece of code that is working fine but it shows apps list in dialogue box:
And I want same feature in this way.May be I need to create views dynamically as per application installed in device.
Please suggest me how can I achieve this

This code will let you find all the apps available for the specified intent:
public static ArrayList<Availables> getAvailableAppsForIntent(Intent intent, Context context) {
ArrayList<Availables> availables = new ArrayList<Availables>();
PackageManager manager = context.getPackageManager();
List<ResolveInfo> infos = manager.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER);
for(ResolveInfo info : infos) {
ActivityInfo activityInfo = info.activityInfo;
IntentFilter filter = info.filter;
if (filter != null && filter.hasAction(intent.getAction())) {
// This activity resolves my Intent with the filter I'm looking for
String activityPackageName = activityInfo.packageName;
String activityName = activityInfo.loadLabel(manager).toString();
String activityFullName = activityInfo.name;
Drawable icon = activityInfo.loadIcon(manager);
Availables available = new Availables(activityName, activityFullName, activityPackageName, icon);
available.setForIntent(intent);
availables.add(available);
}
}
return availables;
}
Availables is just a class i created to store all the informations about the apps but you can manage it however you want.
then you can start the app this way:
Intent intent = available.getForIntent();
intent.setPackage(available.getAppPackage());
context.startActivity(intent);
Hope it helps!

hare is button click event use it
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("text/plain");
String shareBody = "Here is the share content body";
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Subject Here");
intent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
startActivity(Intent.createChooser(intent, "Share via"));

Write code on click of any View:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, "Your Subject Here");
intent.putExtra(Intent.EXTRA_TEXT, "Your Message Here...");
return intent;

Related

Creating custom chooser for share intent by package name

I have a Text in my android activity and I want give the user option to share it on social apps like whatsapp, line, facebook, twitter etc.
But I want to create a custom chooser so that it won't show unintended apps in the chooser.
I'm aware of this snippet
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("text/plain");
startActivity(Intent.createChooser(shareIntent, "Share via"));
How can I make it so that in the chooser it'd only show the apps which I can specify by their package names.
Thanks
Even though I think this question is duplicated, but since I can't find the duplicated question yet, let me provide an answer first.
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent shareInent = new Intent(Intent.ACTION_SEND);
shareInent.setType("text/plain");
List<ResolveInfo> resInfo = activity.getPackageManager().queryIntentActivities(shareInent, 0);
// put the name of the packages you want in this ArrayList
ArrayList<String> wantedPackage = new ArrayList<>();
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
Intent targetedShare = new Intent(android.content.Intent.ACTION_SEND);
targetedShare.setType("text/plain");
String infoPackageName = info.activityInfo.packageName.toLowerCase();
if (wantedPackage.contains(infoPackageName)) {
targetedShare.putExtra(Intent.EXTRA_TEXT, "put your text here");
targetedShare.setPackage(info.activityInfo.packageName.toLowerCase());
targetedShareIntents.add(targetedShare);
resPackageNames.add(infoPackageName);
}
}
Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Chooser title");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
startActivity(chooserIntent);
}

Android Intent directly to Facebook sharing?

Following code works perfectly,
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "text");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Title");
startActivity(Intent.createChooser(sharingIntent, "Share using"));
but it open a list and from this list I have to select Facebook and then everything is smooth.
But is there any config changes that can open Facebook sharing directly instead of going through the menu.
Try the following code, now the intent will open Facebook directly.
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent facebookIntent = getShareIntent("facebook", "subject", "text_or_url");
// subject may not work, but if you have a url place it in text_or_url
if(facebookIntent != null)
targetedShareIntents.add(facebookIntent);
Intent chooser = Intent.createChooser(targetedShareIntents.remove(0), "Delen");
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
startActivity(chooser);
// To precisely get the facebook intent use the following code
private Intent getShareIntent(String type, String subject, String text)
{
boolean found = false;
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("text/plain");
// gets the list of intents that can be loaded.
List<ResolveInfo> resInfo = getActivity().getPackageManager().queryIntentActivities(share, 0);
System.out.println("resinfo: " + resInfo);
if (!resInfo.isEmpty()){
for (ResolveInfo info : resInfo) {
if (info.activityInfo.packageName.toLowerCase().contains(type) ||
info.activityInfo.name.toLowerCase().contains(type) ) {
share.putExtra(Intent.EXTRA_SUBJECT, subject);
share.putExtra(Intent.EXTRA_TEXT, text);
share.setPackage(info.activityInfo.packageName);
found = true;
break;
}
}
if (!found)
return null;
return share;
}
return null;
}
Above code is extracted from this stackoverflow-post
this should be possible, if you get first all activities, that supports your intent and then get the correct and do a explicit call. To get all activities use context.getPackageManager.queryIntentActivities(Intent, int). The coding shouldn't be a big problem.
Check this link: PackageManager docu

How to filter specific apps for ACTION_SEND intent (and set a different text for each app)

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.
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.
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.
OR
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.
OR is it not possible? Are the Facebook and Twitter APIs the only way?
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.
Note that this method also hides all the silly options that I don't want, like sharing over wifi and bluetooth.
Edit:
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: 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.
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.
If you want a customized option then you should not rely on the default dialog provided by android for this action.
What you need to do instead is roll out your own. You will need to query the PackageManager on which packages handle the action you require and then based on the reply, you apply filtering and customized text.
Specifically, take a look at the method queryIntentActivities of the PackageManager class. You build the intent that would launch the default dialog (the ACTION_SEND intent), pass that to this method and you will receive a list of objects that contain info on the activities that can handle that intent. Using that, you can choose the ones you want.
Once you build your list of packages you want to present, you need to build your own list dialog (preferably an activity with the dialog theme) which will display that list.
One thing to note though is that it's very hard to make that custom dialog look like the default one. The problem is that the theme used in that dialog is an internal theme and cannot be used by your application. You can either try to make it as similar to the native one as you want or go for a completely custom look (many apps do that like the gallery app etc)
Found a solution that works for me looking here (see the third comment on the first answer). This code looks for a valid twitter client and uses it to post the tweet. Note: It does not give you an Intent with the various Twitter clients and allow you to choose.
Share using twitter:
Intent shareIntent = findTwitterClient();
shareIntent.putExtra(Intent.EXTRA_TEXT, "test");
startActivity(Intent.createChooser(shareIntent, "Share"));
Calling this method:
public Intent findTwitterClient() {
final String[] twitterApps = {
// package // name - nb installs (thousands)
"com.twitter.android", // official - 10 000
"com.twidroid", // twidroid - 5 000
"com.handmark.tweetcaster", // Tweecaster - 5 000
"com.thedeck.android" }; // TweetDeck - 5 000 };
Intent tweetIntent = new Intent();
tweetIntent.setType("text/plain");
final PackageManager packageManager = getPackageManager();
List<ResolveInfo> list = packageManager.queryIntentActivities(
tweetIntent, PackageManager.MATCH_DEFAULT_ONLY);
for (int i = 0; i < twitterApps.length; i++) {
for (ResolveInfo resolveInfo : list) {
String p = resolveInfo.activityInfo.packageName;
if (p != null && p.startsWith(twitterApps[i])) {
tweetIntent.setPackage(p);
return tweetIntent;
}
}
}
return null;
}
Facebook will be similar using "com.facebook.katana", although you still can't set the message text (deprecated July 2011).
Code source: Intent to open twitter client on Android
Try this one for sharing only three apps-Facebook, Twitter, KakaoStory.
public void onShareClick(View v){
List<Intent> targetShareIntents=new ArrayList<Intent>();
Intent shareIntent=new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
List<ResolveInfo> resInfos=getPackageManager().queryIntentActivities(shareIntent, 0);
if(!resInfos.isEmpty()){
System.out.println("Have package");
for(ResolveInfo resInfo : resInfos){
String packageName=resInfo.activityInfo.packageName;
Log.i("Package Name", packageName);
if(packageName.contains("com.twitter.android") || packageName.contains("com.facebook.katana") || packageName.contains("com.kakao.story")){
Intent intent=new Intent();
intent.setComponent(new ComponentName(packageName, resInfo.activityInfo.name));
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "Text");
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.setPackage(packageName);
targetShareIntents.add(intent);
}
}
if(!targetShareIntents.isEmpty()){
System.out.println("Have Intent");
Intent chooserIntent=Intent.createChooser(targetShareIntents.remove(0), "Choose app to share");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetShareIntents.toArray(new Parcelable[]{}));
startActivity(chooserIntent);
}else{
System.out.println("Do not Have Intent");
showDialaog(this);
}
}
}
Thanks to #dacoinminster. I make some modifications to his answer including package names of the popular apps and sorting of those apps.
List<Intent> targetShareIntents = new ArrayList<Intent>();
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
PackageManager pm = getActivity().getPackageManager();
List<ResolveInfo> resInfos = pm.queryIntentActivities(shareIntent, 0);
if (!resInfos.isEmpty()) {
System.out.println("Have package");
for (ResolveInfo resInfo : resInfos) {
String packageName = resInfo.activityInfo.packageName;
Log.i("Package Name", packageName);
if (packageName.contains("com.twitter.android") || packageName.contains("com.facebook.katana")
|| packageName.contains("com.whatsapp") || packageName.contains("com.google.android.apps.plus")
|| packageName.contains("com.google.android.talk") || packageName.contains("com.slack")
|| packageName.contains("com.google.android.gm") || packageName.contains("com.facebook.orca")
|| packageName.contains("com.yahoo.mobile") || packageName.contains("com.skype.raider")
|| packageName.contains("com.android.mms")|| packageName.contains("com.linkedin.android")
|| packageName.contains("com.google.android.apps.messaging")) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName, resInfo.activityInfo.name));
intent.putExtra("AppName", resInfo.loadLabel(pm).toString());
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "https://website.com/");
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_text));
intent.setPackage(packageName);
targetShareIntents.add(intent);
}
}
if (!targetShareIntents.isEmpty()) {
Collections.sort(targetShareIntents, new Comparator<Intent>() {
#Override
public int compare(Intent o1, Intent o2) {
return o1.getStringExtra("AppName").compareTo(o2.getStringExtra("AppName"));
}
});
Intent chooserIntent = Intent.createChooser(targetShareIntents.remove(0), "Select app to share");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetShareIntents.toArray(new Parcelable[]{}));
startActivity(chooserIntent);
} else {
Toast.makeText(getActivity(), "No app to share.", Toast.LENGTH_LONG).show();
}
}
You can try the code below, it works perfectly.
Here we share to some specific apps, that are Facebook, Messenger, Twitter, Google Plus and Gmail.
public void shareIntentSpecificApps() {
List<Intent> intentShareList = new ArrayList<Intent>();
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
List<ResolveInfo> resolveInfoList = getPackageManager().queryIntentActivities(shareIntent, 0);
for (ResolveInfo resInfo : resolveInfoList) {
String packageName = resInfo.activityInfo.packageName;
String name = resInfo.activityInfo.name;
Log.d(TAG, "Package Name : " + packageName);
Log.d(TAG, "Name : " + name);
if (packageName.contains("com.facebook") ||
packageName.contains("com.twitter.android") ||
packageName.contains("com.google.android.apps.plus") ||
packageName.contains("com.google.android.gm")) {
if (name.contains("com.twitter.android.DMActivity")) {
continue;
}
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName, name));
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, "Your Subject");
intent.putExtra(Intent.EXTRA_TEXT, "Your Content");
intentShareList.add(intent);
}
}
if (intentShareList.isEmpty()) {
Toast.makeText(MainActivity.this, "No apps to share !", Toast.LENGTH_SHORT).show();
} else {
Intent chooserIntent = Intent.createChooser(intentShareList.remove(0), "Share via");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentShareList.toArray(new Parcelable[]{}));
startActivity(chooserIntent);
}
}
This solution shows a list of applications in a ListView dialog that resembles the chooser:
It is up to you to:
obtain the list of relevant application packages
given a package name, invoke the relevant intent
The adapter class:
import java.util.List;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class ChooserArrayAdapter extends ArrayAdapter<String> {
PackageManager mPm;
int mTextViewResourceId;
List<String> mPackages;
public ChooserArrayAdapter(Context context, int resource, int textViewResourceId, List<String> packages) {
super(context, resource, textViewResourceId, packages);
mPm = context.getPackageManager();
mTextViewResourceId = textViewResourceId;
mPackages = packages;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String pkg = mPackages.get(position);
View view = super.getView(position, convertView, parent);
try {
ApplicationInfo ai = mPm.getApplicationInfo(pkg, 0);
CharSequence appName = mPm.getApplicationLabel(ai);
Drawable appIcon = mPm.getApplicationIcon(pkg);
TextView textView = (TextView) view.findViewById(mTextViewResourceId);
textView.setText(appName);
textView.setCompoundDrawablesWithIntrinsicBounds(appIcon, null, null, null);
textView.setCompoundDrawablePadding((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, getContext().getResources().getDisplayMetrics()));
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return view;
}
}
and its usage:
void doXxxButton() {
final List<String> packages = ...;
if (packages.size() > 1) {
ArrayAdapter<String> adapter = new ChooserArrayAdapter(MyActivity.this, android.R.layout.select_dialog_item, android.R.id.text1, packages);
new AlertDialog.Builder(MyActivity.this)
.setTitle(R.string.app_list_title)
.setAdapter(adapter, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item ) {
invokeApplication(packages.get(item));
}
})
.show();
} else if (packages.size() == 1) {
invokeApplication(packages.get(0));
}
}
void invokeApplication(String packageName) {
// given a package name, create an intent and fill it with data
...
startActivityForResult(intent, rq);
}
The cleanest way is to copy the following classes: ShareActionProvider, ActivityChooserView, ActivityChooserModel. Add the ability to filter the intents in the ActivityChooserModel, and the appropriate support methods in the ShareActionProvider. I created the necessary classes, you can copy them into your project (https://gist.github.com/saulpower/10557956). This not only adds the ability to filter the apps you would like to share with (if you know the package name), but also to turn off history.
private final String[] INTENT_FILTER = new String[] {
"com.twitter.android",
"com.facebook.katana"
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.journal_entry_menu, menu);
// Set up ShareActionProvider's default share intent
MenuItem shareItem = menu.findItem(R.id.action_share);
if (shareItem instanceof SupportMenuItem) {
mShareActionProvider = new ShareActionProvider(this);
mShareActionProvider.setShareIntent(ShareUtils.share(mJournalEntry));
mShareActionProvider.setIntentFilter(Arrays.asList(INTENT_FILTER));
mShareActionProvider.setShowHistory(false);
((SupportMenuItem) shareItem).setSupportActionProvider(mShareActionProvider);
}
return super.onCreateOptionsMenu(menu);
}
I have improved #dacoinminster answer and this is the result with an example to share your app:
// Intents with SEND action
PackageManager packageManager = context.getPackageManager();
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(sendIntent, 0);
List<LabeledIntent> intentList = new ArrayList<LabeledIntent>();
Resources resources = context.getResources();
for (int j = 0; j < resolveInfoList.size(); j++) {
ResolveInfo resolveInfo = resolveInfoList.get(j);
String packageName = resolveInfo.activityInfo.packageName;
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setComponent(new ComponentName(packageName,
resolveInfo.activityInfo.name));
intent.setType("text/plain");
if (packageName.contains("twitter")) {
intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.twitter) + "https://play.google.com/store/apps/details?id=" + context.getPackageName());
} else {
// skip android mail and gmail to avoid adding to the list twice
if (packageName.contains("android.email") || packageName.contains("android.gm")) {
continue;
}
intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.largeTextForFacebookWhatsapp) + "https://play.google.com/store/apps/details?id=" + context.getPackageName());
}
intentList.add(new LabeledIntent(intent, packageName, resolveInfo.loadLabel(packageManager), resolveInfo.icon));
}
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, resources.getString(R.string.subjectForMailApps));
emailIntent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.largeTextForMailApps) + "https://play.google.com/store/apps/details?id=" + context.getPackageName());
context.startActivity(Intent.createChooser(emailIntent, resources.getString(R.string.compartirEn)).putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new LabeledIntent[intentList.size()])));
I had same problem and this accepted solution didn't helped me, if someone has same problem you can use my code snippet:
// example of filtering and sharing multiple images with texts
// remove facebook from sharing intents
private void shareFilter(){
String share = getShareTexts();
ArrayList<Uri> uris = getImageUris();
List<Intent> targets = new ArrayList<>();
Intent template = new Intent(Intent.ACTION_SEND_MULTIPLE);
template.setType("image/*");
List<ResolveInfo> candidates = getActivity().getPackageManager().
queryIntentActivities(template, 0);
// remove facebook which has a broken share intent
for (ResolveInfo candidate : candidates) {
String packageName = candidate.activityInfo.packageName;
if (!packageName.equals("com.facebook.katana")) {
Intent target = new Intent(Intent.ACTION_SEND_MULTIPLE);
target.setType("image/*");
target.putParcelableArrayListExtra(Intent.EXTRA_STREAM,uris);
target.putExtra(Intent.EXTRA_TEXT, share);
target.setPackage(packageName);
targets.add(target);
}
}
Intent chooser = Intent.createChooser(targets.remove(0), "Share Via");
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targets.toArray(new Parcelable[targets.size()]));
startActivity(chooser);
}
Intent emailIntent = new Intent(Intent.ACTION_SENDTO,
Uri.fromParts("mailto", "android#gmail.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, text);
startActivity(Intent.createChooser(emailIntent, "Send email..."));
So simple and concise. Thanks to the Open source developer, cketti for sharing this solution:
String mailto = "mailto:bob#example.org" +
"?cc=" + "alice#example.com" +
"&subject=" + Uri.encode(subject) +
"&body=" + Uri.encode(bodyText);
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse(mailto));
try {
startActivity(emailIntent);
} catch (ActivityNotFoundException e) {
//TODO: Handle case where no email app is available
}
And this is the link to his/her gist.

How to customize share intent in Android?

Now i can use the share intent to open the share dialog
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, link);
startActivity(Intent.createChooser(intent, "Share with"));
but i need the dialog not to appear and share directly to one social network for example (FB or twitter)
any advice how to do that ?
There is a way to directly open the intent you wants. You can get the list of intents and open only one.
See this code:
private void initShareIntent(String type) {
boolean found = false;
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("image/jpeg");
// gets the list of intents that can be loaded.
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(share, 0);
if (!resInfo.isEmpty()){
for (ResolveInfo info : resInfo) {
if (info.activityInfo.packageName.toLowerCase().contains(type) ||
info.activityInfo.name.toLowerCase().contains(type) ) {
share.putExtra(Intent.EXTRA_SUBJECT, "subject");
share.putExtra(Intent.EXTRA_TEXT, "your text");
share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(myPath)) ); // Optional, just if you wanna share an image.
share.setPackage(info.activityInfo.packageName);
found = true;
break;
}
}
if (!found)
return;
startActivity(Intent.createChooser(share, "Select"));
}
}
If you wanna open twitter, do that:
initShareIntent("twi");
if facebook:
initShareIntent("face");
if mail:
initShareIntent("mail"); // or "gmail"
If you wanna show a list of intents that match with the type, insted of use the first mach, see this post: Android Intent for Twitter application
No you can't. Intent's are supposed to work this way. If you have to force a particular app to open, use explicit intents if the target apps support those. Without knowing the package names or the component names of the target apps, or the type or mime type of data, you can't force a particular app to work on generalized intents.
First, list all apps to share.
private java.util.List<ResolveInfo> showAllShareApp() {
java.util.List<ResolveInfo> mApps = new ArrayList<ResolveInfo>();
Intent intent = new Intent(Intent.ACTION_SEND, null);
intent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
intent.setType("text/plain");
PackageManager pManager = getPackageManager();
mApps = pManager.queryIntentActivities(intent,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
return mApps;
}
Then, select one
private void share(ResolveInfo appInfo) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
if (appInfo != null) {
sendIntent
.setComponent(new ComponentName(
appInfo.activityInfo.packageName,
appInfo.activityInfo.name));
}
sendIntent.setType("text/plain");
// startActivity(Intent.createChooser(sendIntent, "Share"));
startActivity(sendIntent);
}
Here's an sample project.Hope it helps.
You can get all email client using ACTION_SENDTO like
Intent getMailClients = new Intent(Intent.ACTION_SENDTO);
getMailClients.setData(Uri.parse("mailto:"));
final PackageManager pm = this.getPackageManager();
final List<ResolveInfo> emailsClients = pm.queryIntentActivities(getMailClients, 0);
if (emailsClients.size() == 0) {
Toast.makeText(this, "There are no email clients installed", Toast.LENGTH_LONG).show();
return;
}
and then create your own chooser(dialog with list of founded apps). When user click on item you can do smth like this.
Intent sendMailIntent = new Intent(Intent.ACTION_SEND);
sendMailIntent.setType(some type like text/plain or other you need);
...
there you can set SUBJECT,EMAILTO, attach files
...
final List<ResolveInfo> matches = pm.queryIntentActivities(sendMailIntent, 0);
ResolveInfo sendingProgramm = null;
for (final ResolveInfo info : matches) {
if (info.activityInfo.packageName.equals(clickedResolveInfo.activityInfo.packageName)) {
sendingProgramm = info;
sendMailIntent
.setClassName(sendingProgramm.activityInfo.packageName, sendingProgramm.activityInfo.name);
break;
}
}
startActivity(sendMailIntent);
Maybe it will help you.

How to open Gmail Compose when a button is clicked in Android App?

I am trying to open up Gmail Compose screen when a button is clicked in my Android App.
Do I need some API key for this from Google? or what do I need to do in my button onClickListener?
Any kind of insight is much appreciated.
As JeffC pointed out, it is easy to essentially tell Android that you want to send something email-like and have Android give users a list of choices, which will probably include GMail. If you specifically want GMail, you have to be a bit cleverer. (Note that the correct MIME type is actually "text/plain", not "plain/text". Do to an implementation oddity, GMail seems to be the only activity which responds to the latter, but this isn't a behavior I would count on.)
The following App demonstrates the principle you can follow: actually examine all of the activities which say they can handle your SEND intent and see if any of them look like GMail.
package com.stackoverflow.beekeeper;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import java.util.List;
public class StackOverflowTest extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("text/plain");
final PackageManager pm = getPackageManager();
final List<ResolveInfo> matches = pm.queryIntentActivities(intent, 0);
ResolveInfo best = null;
for (final ResolveInfo info : matches)
if (info.activityInfo.packageName.endsWith(".gm") ||
info.activityInfo.name.toLowerCase().contains("gmail")) best = info;
if (best != null)
intent.setClassName(best.activityInfo.packageName, best.activityInfo.name);
startActivity(intent);
}
}
try {
Intent intent = new Intent (Intent.ACTION_VIEW , Uri.parse("mailto:" + "your_email"));
intent.putExtra(Intent.EXTRA_SUBJECT, "your_subject");
intent.putExtra(Intent.EXTRA_TEXT, "your_text");
startActivity(intent);
} catch (ActivityNotFoundException e){
//TODO smth
}
I don't know that you can specifically launch gmail. Have you tried this in your onClickListener
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/plain");
startActivity(emailIntent);
You can find more details here: Email android intent
You just place below code inside your click event. Will open directly gmail as compose mode, Output screenshot attached below.
Happy coding :-)
code :
Intent intent=new Intent(Intent.ACTION_SEND);
String[] recipients={"mailto#gmail.com"};
intent.putExtra(Intent.EXTRA_EMAIL, recipients);
intent.putExtra(Intent.EXTRA_SUBJECT,"Subject text here...");
intent.putExtra(Intent.EXTRA_TEXT,"Body of the content here...");
intent.putExtra(Intent.EXTRA_CC,"mailcc#gmail.com");
intent.setType("text/html");
intent.setPackage("com.google.android.gm");
startActivity(Intent.createChooser(intent, "Send mail"));
Output :
Just Place the set of code in your click event/trigger event and it will directly navigate you to the native gmail application with all the details pre-filled.
All the email attributes/details are there in the set of code below(Comments added).
Intent intent = new Intent(Intent.ACTION_SEND);
String[] recipients = {"recipient#gmail.com"};//Add multiple recipients here
intent.putExtra(Intent.EXTRA_EMAIL, recipients);
intent.putExtra(Intent.EXTRA_SUBJECT, "Mail Subject"); //Add Mail Subject
intent.putExtra(Intent.EXTRA_TEXT, "Enter your mail body here...");//Add mail body
intent.putExtra(Intent.EXTRA_CC, "mailcc#gmail.com");//Add CC emailid's if any
intent.putExtra(Intent.EXTRA_BCC, "mailbcc#gmail.com");//Add BCC email id if any
intent.setType("text/html");
intent.setPackage("com.google.android.gm");//Added Gmail Package to forcefully open Gmail App
startActivity(Intent.createChooser(intent, "Send mail"));
#HAPPY_CODING
public static void openGmail(Activity activity,String[] email, String subject, String content) {
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.putExtra(Intent.EXTRA_EMAIL, email);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.setType("text/plain");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, content);
final PackageManager pm = activity.getPackageManager();
final List<ResolveInfo> matches = pm.queryIntentActivities(emailIntent, 0);
ResolveInfo best = null;
for(final ResolveInfo info : matches)
if (info.activityInfo.packageName.endsWith(".gm") || info.activityInfo.name.toLowerCase().contains("gmail"))
best = info;
if (best != null)
emailIntent.setClassName(best.activityInfo.packageName, best.activityInfo.name);
activity.startActivity(emailIntent);
}
<TextView
android:id="#+id/EmailId"
android:linksClickable="true"
android:autoLink="email"
android:text="info#stackoverflow.com"
/>
This is the best method to send email on click of textView.
This code will directly start the gmail application to send an email.
I found out using this post that the important part here is to find the "packageName" and the "activityInfo.name"
I wanted to only use gmail without a chooser. Note that the package name is hard coded so if Gmail changes its packagename it won't work any more.
The key to this was the setComponent where the first param is the package name and the second param is the activityInfo name.
But like i said use with caution, I repeat myself; if the user doesn't have the gmail app installed or gmail changes its package name or Activty name to send an email this (hard)code will break. Thy have been warned ;)
Here is my code
Intent myIntent = new Intent(Intent.ACTION_SEND);
PackageManager pm = getPackageManager();
Intent tempIntent = new Intent(Intent.ACTION_SEND);
tempIntent.setType("*/*");
List<ResolveInfo> resInfo = pm.queryIntentActivities(tempIntent, 0);
for (int i = 0; i < resInfo.size(); i++) {
ResolveInfo ri = resInfo.get(i);
if (ri.activityInfo.packageName.contains("android.gm")) {
myIntent.setComponent(new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name));
myIntent.setAction(Intent.ACTION_SEND);
myIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"exampleto#gmail.com"});
myIntent.setType("message/rfc822");
myIntent.putExtra(Intent.EXTRA_TEXT, "extra text");
myIntent.putExtra(Intent.EXTRA_SUBJECT, "Extra subject");
myIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("uri://your/uri/string");
}
}
startActivity(myIntent);
You can use Simple Intent.ACTION_SEND intent
set Intent.EXTRA_EMAIL for array of emails
set Intent.EXTRA_SUBJECT for subject line in email composer
Explore more EXTRA options available here -> https://developer.android.com/guide/components/intents-common#Email
Here's a quick code snippet
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"test#gmail.com"});
intent.putExtra(Intent.EXTRA_SUBJECT, "Feedback");
if (intent.resolveActivity(ctx.getPackageManager()) != null) {
startActivity(intent);
}
if you don't get anything in this line
final List<ResolveInfo> matches = pm.queryIntentActivities(intent, 0);
then replace this line with
final List<ResolveInfo> matches = pm.queryIntentActivities(intent, 1);
Intent intent = new Intent(Intent.ACTION_SEND).setType("text/plain")
.putExtra(Intent.EXTRA_EMAIL, new String[]{emails});
List<ResolveInfo> matches = activity.getPackageManager().queryIntentActivities(intent, 0);
ResolveInfo best = null;
for (ResolveInfo info : matches) {
if (info.activityInfo.packageName.endsWith(".gm") || info.activityInfo.name.toLowerCase().contains("gmail")) {
best = info;
}
}
if (best != null) {
intent.setClassName(best.activityInfo.packageName,best.activityInfo.name);
}
activity.startActivity(intent);

Categories

Resources