How to limit the email intent in android app? - android

I am using this code to use email application from my app.
String mailText = "Full Name:" + fname.getText().toString();
String subject = "Support";
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_EMAIL, new String[] { "support#roncocala.com" });
email.putExtra(Intent.EXTRA_SUBJECT, subject);
email.setType("plain/text");
email.putExtra(Intent.EXTRA_TEXT, mailText);
startActivity(Intent.createChooser(email, "Choose an Email client :"));
But it shows extra applications like SKype and ES File Lan . Is there a way to limit these application to mail applications like gmail,yahoo,hotmail. Please help.Thanks.

To get only email client you need to use android.content.Intent.ACTION_SENDTO :
new Intent(Intent.ACTION_SENDTO); // return only the list of e-mail clients
you need to have configured an email account on those email client app or you'll have the error : "No application can perform this action".

ACTION_SENDTO only seems to be working for newer OS (at least API LEVEL 17+).
Unfortunately, this is the "best" current way of limiting the application list if you want to support older Android OS.
emailIntent.setType("message/rfc822");

None of the above solutions worked for me. After a lot of searching and testing, I finally found a good solution. Thanks to the Open source developer, cketti for sharing his/her concise and neat 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.

Related

How to filter the apps that show up when sharing intent Android?

I know this has been asked before and I reference one of the answers but I can't get my code to work the way it should. I have a simple note-taking app, which allows the user to share notes through external applications. The code is supposed to filter the apps so the user can only share to facebook, twitter, mms, gmail, and email (so I thought). I took it from the top answer here How to filter specific apps for ACTION_SEND intent (and set a different text for each app). When I click on the button that launches the method to share intents, I do get mms, gmail, facebook twitter, and email, but I also get google drive, android beam, evernote, twitter direct message, facebook messenger and snapchat.
The only apps that the information gets sent correctly to are mms, email and gmail. Facebook doesn't work, there's some comments below on why, and twitter I'm not sure of because I don't have an account to test it out. I don't have the code to check if the packageName contains "drive" or "googledrive", but I can still share to drive and the data from my note gets passed along. I want to be able to send the note text and the note title however (2 editText fields in my app), but I don't know how to since I don't know what the package name is.
For the apps that don't work or I want to remove from the list of choices, how can I get rid of them? Here is the code:
public void sendNote(View view) {
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, titleEditor.getText().toString());
emailIntent.putExtra(Intent.EXTRA_SUBJECT, noteEditor.getText().toString());
emailIntent.setType("message/rfc822");
PackageManager pm = getPackageManager();
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
Intent openInChooser = Intent.createChooser(emailIntent, titleEditor.getText().toString() + ": " + noteEditor.getText().toString());
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, titleEditor.getText().toString() + ": " + noteEditor.getText().toString());
} 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, titleEditor.getText().toString() + ": " + noteEditor.getText().toString());
} else if(packageName.contains("mms")) {
intent.putExtra(Intent.EXTRA_TEXT, titleEditor.getText().toString() + ": " + noteEditor.getText().toString());
} 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, noteEditor.getText().toString());
intent.putExtra(Intent.EXTRA_SUBJECT, titleEditor.getText().toString());
intent.setType("message/rfc822");
}
//else if (packageName.contains("drive")) {
//intent.putExtra(Intent.EXTRA_TEXT, titleEditor.getText().toString() + ": " + noteEditor.getText().toString());
//}
else {
}
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 have an else if near the bottom that is commented out. That was my attempt in finding the google drive packageName and sending the intent so the user can still use that application, it didn't work. Like I said earlier, drive gets information sent to it, but it's just the note text, not the title and text like I want it to be.
So I have 2 questions.
How can I filter out all of the apps that I don't want the user to be able to send information to so they don't even show up as an option, lets take twitter for example.
If the above is not possible, how can I find the package names for these different apps? For Google Drive, I tried using the commented out else if statement to send an intent to the app there but it never executed. I've searched everywhere to get intents for google drive but I can't get the package name to get my code working.
Thanks in advance

E-mail app not installed, Android

I'm trying to send an email after a survey is done. However when I try and use this line
startActivity(Intent.createChooser(emailIntent, "Email Reference Number"));
The dialog pops up that says "Email Reference Number"but below it says "No apps can perform this action". I'm using a Nexus 7 and I have gmail set up.
Is there a better way to bring up the option to choose an e-mail?
Thanks
Just in case here is the full email code
Intent emailIntent = new Intent(android.content.Intent.ACTION_SENDTO);
emailIntent.setType("message/rfc822");
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Reference Number");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, Html.fromHtml("<b>Thank you for your business, here is your reference number: " + ref + "</b>"));
startActivity(Intent.createChooser(emailIntent,"Email Reference Number"));
This works on my Nexus 7:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_SUBJECT, "Reference Number");
intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml("<b>Thank you for your business, here is your reference number: " + ref + "</b>"));
startActivity(Intent.createChooser(intent,"Email Reference Number"));
If you use Intent.ACTION_SENDTO, you need to call setData() to set an appropriate mailto: URI.
You can also use the Intent.ACTION_SEND action and specify the recipient with the Intent.EXTRA_EMAIL extra.

Android not prompting me apps with email Capability

I'm trying to make a app, that takes information of some sort, then i want it to email that information to my gmail. I have found working code but when i load it onto my phone and run it and got all the info loaded into the app,and click the email, from what i understand its suppose to filter apps(on my phone) that are capable to send the email but I'm not getting anything, even though i have the default Email app that comes on the phone and i have Gmail.
public void Done(View view) {
Intent email = new Intent(Intent.ACTION_SENDTO); // it's not ACTION_SEND
email.putExtra(Intent.EXTRA_EMAIL, "some#gmail.com");
email.putExtra(Intent.EXTRA_SUBJECT, "OverStock Changes");
email.putExtra(Intent.EXTRA_TEXT, printReport());
email.setType("message/rfc822");
startActivity(Intent.createChooser(email, "Email"));
}
See answer for ACTION_SENDTO for sending an email
If you use ACTION_SENDTO, putExtra() does not work to add subject and
text to the intent. Use setData() and the Uri tool add subject and
text.
This example works for me:
// ACTION_SENDTO filters for email apps (discard bluetooth and others)
String uriText =
"mailto:youremail#gmail.com" +
"?subject=" + URLEncoder.encode("some subject text here") +
"&body=" + URLEncoder.encode("some text here");
Uri uri = Uri.parse(uriText);
Intent sendIntent = new Intent(Intent.ACTION_SENDTO);
sendIntent.setData(uri);
startActivity(Intent.createChooser(sendIntent, "Send email"));
Otherwise use ACTION_SEND as mentioned:
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"mail#mail.com","mail2#mail.com"});
intent.putExtra(Intent.EXTRA_SUBJECT,"subject");
intent.putExtra(Intent.EXTRA_TEXT, "mail content");
startActivity(Intent.createChooser(intent, "title of dialog"));

Android Button onclick submit to email

I have been working with Java and Xml for a few months now, and have learned a great deal thanks to everyones help on StackOverflow.
My question is about java programming for android in relation to the submit button.
Currently I am trying to figure out how to submit a value to an email address (behind the scenes)
Lets say we have a text field and a button; I want to take the value entered in the text field, and submit that to an email address onclick.
I am unable to find anything online that shows me how to do this.
Thank you in advance for reading through my post and I look forward to your suggestions.
This is a great example of how using Intents can come in great handy!
Android has a bunch of pre-defined Intents that do certain things within the system; you may have clicked on a picture before and a dialog popped up asking whether you would like to view it in your gallery or in a third-party app such as Astro. The viewing of an image has its own pre-determined intent.
Sending an email also has its own pre-determined intent: android.content.Intent.ACTION_SEND. You'll need to create an intent with that property and then attach extra information (ie. the address to send to, the subject/message body, etc.).
Example code:
// Data members
private Intent emailIntent;
private String feedback;
private EditText feedbackBox;
// Create the Intent, and give it the pre-defined value
// that the Android machine automatically associates with
// sending an email.
emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("plain/text");
// Put extra information into the Intent, including the email address
// that you wish to send to, and any subject (optional, of course).
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"your_email#whatever.com"});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Insert subject here");
// Acquire feedback from an EditText and save it to a String.
feedback = feedbackBox.getText().toString();
// Put the message into the Intent as more extra information,
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, feedback);
// Start the Intent, which will launch the user's email
// app (make sure you save any necessary information in YOUR app
// in your onPause() method, as launching the email Intent will
// pause your app). This will create what I discussed above - a
// popup box that the user can use to determine which app they would like
// to use in order to send the email.
startActivity(Intent.createChooser(emailIntent, "Insert title for dialog box."));
I hoped this helped!!
Some sources you might like to check out:
http://developer.android.com/guide/topics/intents/intents-filters.html
http://developer.android.com/reference/android/content/Intent.html#ACTION_SEND
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, someEditText.getText());
startActivity(Intent.createChooser(emailIntent, "Send someone an email..."));
try this
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:Type email address here"));
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
It works good
String mail=mailid.getText().toString();
String msubject=subject.getText().toString();
String mbody=body.getText().toString();
Log.i("Send email", "");
String[] TO = {mail};
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setData(Uri.parse("mailto:"));
emailIntent.setType("text/plain");
emailIntent.putExtra(Intent.EXTRA_EMAIL, TO);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Static subject "+ msubject);
emailIntent.putExtra(Intent.EXTRA_TEXT, "Static body "+ mbody);
try {
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
finish();
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(MainActivity.this, "There is no email client installed.", Toast.LENGTH_SHORT).show();
}

Android Intent Chooser to only show E-mail option

My app integrates e-mail where the user can submit a bug report, feedback, etc. from the app directly. I'm using the application/octet-stream as the SetType for the Intent. When you go to submit the e-mail you get the content chooser and it shows various items from Evernote, Facebook, E-mail, etc.
How can I get this chooser to only show E-mail so as not to confuse the user with all these other items that fit the content chooser type?
Thank you.
To solve this issue simply follow the official documentation. The most important consideration are:
The flag is ACTION_SENDTO, and not ACTION_SEND.
The setData of method of the intent,
intent.setData(Uri.parse("mailto:")); // only email apps should handle this
If you send an empty Extra, the if() at the end won't work and the app won't launch the email client.
This works for me. According to Android documentation. If you want to ensure that your intent is handled only by an email app (and not other text messaging or social apps), then use the ACTION_SENDTO action and include the "mailto:" data scheme. For example:
public void composeEmail(String[] addresses, String subject) {
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:")); // only email apps should handle this
intent.putExtra(Intent.EXTRA_EMAIL, addresses);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
https://developer.android.com/guide/components/intents-common.html#Email
I am presuming that you are using the ACTION_SEND Intent action, since you did not bother to actually state what you're using, but you agreed with #Aleadam's comment.
I'm using the application/octet-stream as the SetType for the Intent.
Nothing in that sentence limits things to email.
ACTION_SEND is a generic Intent action that can be supported by any application that wants to. All you do is indicate what data you are sharing and the MIME type of that data -- from there, it is up to the user to choose from available activities.
As #Jasoon indicates, you can try message/rfc822 as the MIME type. However, that is not indicating "only offer email clients" -- it indicates "offer anything that supports message/rfc822 data". That could readily include some application that are not email clients.
If you specifically want to send something by email, integrate JavaMail into your app, or write an email forwarding script on your Web server and invoke it, or something. If you use ACTION_SEND, you are implicitly stating that it is what the user wants that matters, and you want the user to be able to send such-and-so data by whatever means the user chooses.
Just struggled with this problem while implementing a Magic Link feature, a chooser intent for all installed email apps:
Chooser Intent Screenshot
private void openEmailApp() {
List<Intent> emailAppLauncherIntents = new ArrayList<>();
//Intent that only email apps can handle:
Intent emailAppIntent = new Intent(Intent.ACTION_SENDTO);
emailAppIntent.setData(Uri.parse("mailto:"));
emailAppIntent.putExtra(Intent.EXTRA_EMAIL, "");
emailAppIntent.putExtra(Intent.EXTRA_SUBJECT, "");
PackageManager packageManager = getPackageManager();
//All installed apps that can handle email intent:
List<ResolveInfo> emailApps = packageManager.queryIntentActivities(emailAppIntent, PackageManager.MATCH_ALL);
for (ResolveInfo resolveInfo : emailApps) {
String packageName = resolveInfo.activityInfo.packageName;
Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName);
emailAppLauncherIntents.add(launchIntent);
}
//Create chooser
Intent chooserIntent = Intent.createChooser(new Intent(), "Select email app:");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, emailAppLauncherIntents.toArray(new Parcelable[emailAppLauncherIntents.size()]));
startActivity(chooserIntent);
}
There is a way more generic to do that, working with any MIME type.
See this post: How to customize share intent in Android?
It is possible to limit the choices of an intent chooser to just a few options. The code in the answer to this question is a good example. In essence, you would have to create a List of LabeledIntents to provide to the intent chooser, that will then include it in its list. Note that this solution works not on exclusion (certain apps are excluded while the rest remain) but instead you have to pick which apps to display. Hope it helps!
It works on all devices. It will show only Email Apps
public static void shareViaMail(Activity activity, String title, String body, String filePath) {
Uri URI = Uri.parse("file://" + filePath);
final Intent emailIntent = new Intent(Intent.ACTION_VIEW);
emailIntent.setData(Uri.parse("mailto:"));
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"contact#brightsociety.com"});
if (URI != null) {
emailIntent.putExtra(Intent.EXTRA_STREAM, URI);
}
try {
activity.startActivity(emailIntent);
} catch (Exception e) {
((BaseActivity) activity).showToast("Gmail App is not installed");
e.printStackTrace();
}
}
Kotlin Answer
If you need to show only email apps and then you want to open only inbox (not open new email writing), you need to do A and B:
A) Add below code in your AndroidManifest.xml file for Android 11 because of package visibility update of Android 11 :
<queries>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
</intent>
<intent>
<action android:name="android.intent.action.CHOOSER" />
</intent>
</queries>
B) Use below function to show email chooser:
// Show email app list.
fun showEmailAppList() {
// Email app list.
val emailAppLauncherIntents: MutableList<Intent?> = ArrayList()
// Create intent which can handle only by email apps.
val emailAppIntent = Intent(Intent.ACTION_SENDTO)
emailAppIntent.data = Uri.parse("mailto:")
// Find from all installed apps that can handle email intent and check version.
val emailApps = packageManager.queryIntentActivities(
emailAppIntent,
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) 0 else PackageManager.MATCH_ALL
)
// Collect email apps and put in intent list.
for (resolveInfo in emailApps) {
val packageName = resolveInfo.activityInfo.packageName
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
emailAppLauncherIntents.add(launchIntent)
}
// Create chooser with created intent list to show email apps of device.
val chooserIntent = Intent.createChooser(Intent(), "OPEN EMAIL APP")
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, emailAppLauncherIntents.toTypedArray())
startActivity(chooserIntent)
}
Result:
It works on all devices.It will show only Email Apps
public static void shareViaMail(Activity activity, String title, String body, String filePath) {
Uri URI = Uri.parse("file://" + filePath);
final Intent emailIntent = new Intent(Intent.ACTION_VIEW);
emailIntent.setData(Uri.parse("mailto:"));
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"xyz#gmail.com"});
/*if you want to attach something*/
if (URI != null) {
emailIntent.putExtra(Intent.EXTRA_STREAM, URI);
}
try {
activity.startActivity(emailIntent);
} catch (Exception e) {
((BaseActivity) activity).showToast("Gmail App is not installed");
e.printStackTrace();
}
}
Solution is very simple:
Intent testIntent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.parse("mailto:?subject=" + "blah blah subject" + "&body=" + "blah blah body" + "&to=" + "sendme#me.com");
testIntent.setData(data);
startActivity(testIntent);
See: http://www.gaanza.com/blog/email-client-intent-android/
After a lot of searching and testing, I finally found a perfect solution. Thanks to the Open source developer, cketti for sharing his/her concise and neat 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.

Categories

Resources