Only Email apps to resolve an Intent - android

I have a problem .. I want only email activities to resolve intent ACTION.SEND but beside email I get other apps as well (e.g TubeMate) even though I have set the mime type as 'message/rfc822' ... Any idea how can I get Email applications to resolve it ..

String recepientEmail = ""; // either set to destination email or leave empty
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:" + recepientEmail));
startActivity(intent);
The point is to use ACTION_SENDTO as action and mailto: as data. If you want to let the user specify the destination email, use just mailto:; if you specify email yourself, use mailto:name#example.com
Suggested method filters all the application, that can send email(such as default email app or gmail)

Here is how I send email with attachments (proved to work with attachments of various MIME types, even in the same email) and only allow email apps (it also has a solution for cases that no app support "mailto").
At first, we try and get activities that support mailto: format. If none are found then we get all activities that supports the message/rfc822 MIME type.
We select the default app (if there is a default) or allow the user to select from the available apps.
If no app supports mailto: and message/rfc822, then we use the default chooser.
public static void sendEmail(final Context p_context, final String p_subject, final String p_body, final ArrayList<String> p_attachments)
{
try
{
PackageManager pm = p_context.getPackageManager();
ResolveInfo selectedEmailActivity = null;
Intent emailDummyIntent = new Intent(Intent.ACTION_SENDTO);
emailDummyIntent.setData(Uri.parse("mailto:some#example.com"));
List<ResolveInfo> emailActivities = pm.queryIntentActivities(emailDummyIntent, 0);
if (null == emailActivities || emailActivities.size() == 0)
{
Intent emailDummyIntentRFC822 = new Intent(Intent.ACTION_SEND_MULTIPLE);
emailDummyIntentRFC822.setType("message/rfc822");
emailActivities = pm.queryIntentActivities(emailDummyIntentRFC822, 0);
}
if (null != emailActivities)
{
if (emailActivities.size() == 1)
{
selectedEmailActivity = emailActivities.get(0);
}
else
{
for (ResolveInfo currAvailableEmailActivity : emailActivities)
{
if (true == currAvailableEmailActivity.isDefault)
{
selectedEmailActivity = currAvailableEmailActivity;
}
}
}
if (null != selectedEmailActivity)
{
// Send email using the only/default email activity
sendEmailUsingSelectedEmailApp(p_context, p_subject, p_body, p_attachments, selectedEmailActivity);
}
else
{
final List<ResolveInfo> emailActivitiesForDialog = emailActivities;
String[] availableEmailAppsName = new String[emailActivitiesForDialog.size()];
for (int i = 0; i < emailActivitiesForDialog.size(); i++)
{
availableEmailAppsName[i] = emailActivitiesForDialog.get(i).activityInfo.applicationInfo.loadLabel(pm).toString();
}
AlertDialog.Builder builder = new AlertDialog.Builder(p_context);
builder.setTitle(R.string.select_mail_application_title);
builder.setItems(availableEmailAppsName, new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
sendEmailUsingSelectedEmailApp(p_context, p_subject, p_body, p_attachments, emailActivitiesForDialog.get(which));
}
});
builder.create().show();
}
}
else
{
sendEmailUsingSelectedEmailApp(p_context, p_subject, p_body, p_attachments, null);
}
}
catch (Exception ex)
{
Log.e(TAG, "Can't send email", ex);
}
}
protected static void sendEmailUsingSelectedEmailApp(Context p_context, String p_subject, String p_body, ArrayList<String> p_attachments, ResolveInfo p_selectedEmailApp)
{
try
{
Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
String aEmailList[] = { "some#example.com"};
emailIntent.putExtra(Intent.EXTRA_EMAIL, aEmailList);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, null != p_subject ? p_subject : "");
emailIntent.putExtra(Intent.EXTRA_TEXT, null != p_body ? p_body : "");
if (null != p_attachments && p_attachments.size() > 0)
{
ArrayList<Uri> attachmentsUris = new ArrayList<Uri>();
// Convert from paths to Android friendly Parcelable Uri's
for (String currAttachemntPath : p_attachments)
{
File fileIn = new File(currAttachemntPath);
Uri currAttachemntUri = Uri.fromFile(fileIn);
attachmentsUris.add(currAttachemntUri);
}
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachmentsUris);
}
if (null != p_selectedEmailApp)
{
Log.d(TAG, "Sending email using " + p_selectedEmailApp);
emailIntent.setComponent(new ComponentName(p_selectedEmailApp.activityInfo.packageName, p_selectedEmailApp.activityInfo.name));
p_context.startActivity(emailIntent);
}
else
{
Intent emailAppChooser = Intent.createChooser(emailIntent, "Select Email app");
p_context.startActivity(emailAppChooser);
}
}
catch (Exception ex)
{
Log.e(TAG, "Error sending email", ex);
}
}

private void sendEmail(Connect connect) {
Intent email = new Intent(Intent.ACTION_SENDTO);
email.setData(Uri.parse("mailto:"));
email.putExtra(Intent.EXTRA_EMAIL, new String[]{connect.getEmail()});
email.putExtra(Intent.EXTRA_SUBJECT, "");
email.putExtra(Intent.EXTRA_TEXT, "");
try {
startActivity(Intent.createChooser(email, getString(R.string.choose_email_client)));
} catch (ActivityNotFoundException activityNotFoundException) {
UIUtils.showShortSnackBar(fragmentConnectLayout, getString(R.string.no_email_client));
}
}
Refer https://developer.android.com/guide/components/intents-common.html#Email

In Android, there's no such thing as an email activity.
There's also no intent filter that can be created to include only email applications.
Each application (or activity) can define its own intent filters.
So when using intent ACTION_SEND, you'll have to rely on the users intelligence to pickhis favorite email app from the chooser (and not TubeMate).

u can also use:
//writes messages only to email clients
public void setWriteEmailButton() {
btnWriteMail.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent i = new Intent(Intent.ACTION_SENDTO);
i.setData(Uri.parse("mailto:"));
i.putExtra(Intent.EXTRA_EMAIL , new String[]{mConsultantInfos.getConsultantEMail()});
i.putExtra(Intent.EXTRA_SUBJECT, mContext.getString(R.string.txtSubjectConsultantMail));
i.putExtra(Intent.EXTRA_TEXT , "");
try {
startActivity(Intent.createChooser(i, mContext.getString(R.string.txtWriteMailDialogTitle)));
} catch (android.content.ActivityNotFoundException ex) {
UI.showShortToastMessage(mContext, R.string.msgNoMailClientsInstalled);
}
}
});
}
have fun (combination of both ;))

This work for me to open only email apps:
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:jorgesys12#gmail.com"));
startActivity(intent);

Try this
String subject = "Feedback";
String bodyText = "Enter text email";
String mailto = "mailto:bob#example.org" +
"?cc=" + "" +
"&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
}
Credit: https://medium.com/#cketti/android-sending-email-using-intents-3da63662c58f

When I use intent android.content.Intent.ACTION_SENDTO doesn't work for me because it shows many apps, some apps are not email clients. I found this way and it works perfectly for me.
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);

This works for me
Intent intent = new Intent("android.intent.action.SENDTO", Uri.fromParts("mailto", "yourmail#gmail.com", null));
intent.putExtra("android.intent.extra.SUBJECT", "Enter Subject Here");
startActivity(Intent.createChooser(intent, "Select an email client"));

Please check : https://developer.android.com/guide/components/intents-common#ComposeEmail
String[] sendTo = {}; // people who will receive the email
String subject = "implicit intent | sending email";
String message = "Hi, this is just a test to check implicit intent.";
Intent email = new Intent(Intent.ACTION_SENDTO);
email.setData(Uri.parse("mailto:")); // only email apps should handle this
email.putExtra(Intent.EXTRA_EMAIL, sendTo);
email.putExtra(Intent.EXTRA_SUBJECT, subject);// email subject / title
email.putExtra(Intent.EXTRA_TEXT, message);//message that you want to send
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(email, "Choose an Email client :");
// Verify the original intent will resolve to at least one activity
if (chooser.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}

This is an absolutely simple and 100% working approach. Thanks to the Open source developer, cketti for sharing this 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.

Here's a code snippet that launches ONLY email apps.
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:example#example.com"));
intent.putExtra(Intent.EXTRA_SUBJECT, "This is the subject"));
intent.putExtra(Intent.EXTRA_TEXT, "Hi, how're you doing?"));
if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivity(intent);
}
I hope this helps.

Following three lines of code is sufficient to finish your task, nothing EXTRAS needed. Hope it helps.
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:destination_gmail#gmail.com"));
startActivity(Intent.createChooser(intent, "Send email using.."));

You can also use this. It's more efficient
Intent mailIntent = new Intent(Intent.ACTION_SEND);
String mailTo[] = new String[] { "MAIL_TO_1", "MAIL_TO_2" };
mailIntent.putExtra(Intent.EXTRA_EMAIL, mailTo);
mailIntent.putExtra(Intent.EXTRA_SUBJECT, "Your subject");
mailIntent.putExtra(Intent.EXTRA_TEXT, "MailsBody");
mailIntent.setType("plain/text");
startActivity(Intent.createChooser(mailIntent, "only email client"));
This code sample show only email client which are currently installed on your device

Related

Send text to specific contact programmatically (whatsapp)

I wanted to know how I can send text to a specific whatsapp contact. I found some code to view a specific contact, but not to send data.
Cursor c = getContentResolver().query(ContactsContract.Data.CONTENT_URI,
new String[] { ContactsContract.Contacts.Data._ID }, ContactsContract.Data.DATA1 + "=?",
new String[] { id }, null);
c.moveToFirst();
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("content://com.android.contacts/data/" + c.getString(0)));
startActivity(i);
c.close();
This works fine for viewing a whatsapp-contact, but how can I add some text now? Or didn't the Whatsapp-developer implement such kind of an api?
I've found the right way to do this:
Source code: phone and message are both String.
PackageManager packageManager = context.getPackageManager();
Intent i = new Intent(Intent.ACTION_VIEW);
try {
String url = "https://api.whatsapp.com/send?phone="+ phone +"&text=" + URLEncoder.encode(message, "UTF-8");
i.setPackage("com.whatsapp");
i.setData(Uri.parse(url));
if (i.resolveActivity(packageManager) != null) {
context.startActivity(i);
}
} catch (Exception e){
e.printStackTrace();
}
Enjoy yourself!
I think the answer is a mix of your question and this answer here: https://stackoverflow.com/a/15931345/734687
So I would try the following code:
change ACTION_VIEW to ACTION_SENDTO
set the Uri as you did
set the package to whatsapp
Intent i = new Intent(Intent.ACTION_SENDTO, Uri.parse("content://com.android.contacts/data/" + c.getString(0)));
i.setType("text/plain");
i.setPackage("com.whatsapp"); // so that only Whatsapp reacts and not the chooser
i.putExtra(Intent.EXTRA_SUBJECT, "Subject");
i.putExtra(Intent.EXTRA_TEXT, "I'm the body.");
startActivity(i);
I looked into the Whatsapp manifest and saw that ACTION_SEND is registered to the activity ContactPicker, so that will not help you. However ACTION_SENDTO is registered to the activity com.whatsapp.Conversation which sounds more adequate for your problem.
Whatsapp can work as a replacement for sending SMS, so it should work like SMS. When you do not specify the desired application (via setPackage) Android displays the application picker. Thererfor you should just look at the code for sending SMS via intent and then provide the additional package information.
Uri uri = Uri.parse("smsto:" + smsNumber);
Intent i = new Intent(Intent.ACTION_SENDTO, uri);
i.putExtra("sms_body", smsText);
i.setPackage("com.whatsapp");
startActivity(i);
First try just to replace the intent ACTION_SEND to ACTION_SENDTO . If this does not work than provide the additional extra sms_body. If this does not work than try to change the uri.
Update
I tried to solve this myself and was not able to find a solution. Whatsapp is opening the chat history, but doesn't take the text and send it. It seems that this functionality is just not implemented.
I have done it!
private void openWhatsApp() {
String smsNumber = "7****"; // E164 format without '+' sign
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.putExtra("jid", smsNumber + "#s.whatsapp.net"); //phone number without "+" prefix
sendIntent.setPackage("com.whatsapp");
if (intent.resolveActivity(getActivity().getPackageManager()) == null) {
Toast.makeText(this, "Error/n" + e.toString(), Toast.LENGTH_SHORT).show();
return;
}
startActivity(sendIntent);
}
This approach works with WhatsApp Business app as well!
Change package name as sendIntent.setPackage("com.whatsapp.w4b"); for WhatsApp Business.
Great hack Rishabh, thanks a lot, I was looking for this solution since last 3 years.
As per the Rishabh Maurya's answer above, I have implemented this code which is working fine for both text and image sharing on WhatsApp.
Note that in both the cases it opens a whatsapp conversation (if toNumber exists in users whatsapp contact list), but user have to click send button to complete the action. That means it helps in skipping contact selection step.
For text messages
String toNumber = "+91 98765 43210"; // contains spaces.
toNumber = toNumber.replace("+", "").replace(" ", "");
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.putExtra("jid", toNumber + "#s.whatsapp.net");
sendIntent.putExtra(Intent.EXTRA_TEXT, message);
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setPackage("com.whatsapp");
sendIntent.setType("text/plain");
startActivity(sendIntent);
For sharing images
String toNumber = "+91 98765 43210"; // contains spaces.
toNumber = toNumber.replace("+", "").replace(" ", "");
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
sendIntent.putExtra("jid", toNumber + "#s.whatsapp.net");
sendIntent.putExtra(Intent.EXTRA_TEXT, message);
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setPackage("com.whatsapp");
sendIntent.setType("image/png");
context.startActivity(sendIntent);
Enjoy WhatsApping!
It lets you open WhatsApp conversation screen for that specific user you are trying to communicate with:
private void openWhatsApp() {
String smsNumber = "91XXXXXXXX20";
boolean isWhatsappInstalled = whatsappInstalledOrNot("com.whatsapp");
if (isWhatsappInstalled) {
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.setComponent(new ComponentName("com.whatsapp", "com.whatsapp.Conversation"));
sendIntent.putExtra("jid", PhoneNumberUtils.stripSeparators(smsNumber) + "#s.whatsapp.net");//phone number without "+" prefix
startActivity(sendIntent);
} else {
Uri uri = Uri.parse("market://details?id=com.whatsapp");
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
Toast.makeText(this, "WhatsApp not Installed",
Toast.LENGTH_SHORT).show();
startActivity(goToMarket);
}
}
private boolean whatsappInstalledOrNot(String uri) {
PackageManager pm = getPackageManager();
boolean app_installed = false;
try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
app_installed = true;
} catch (PackageManager.NameNotFoundException e) {
app_installed = false;
}
return app_installed;
}
Check out my answer : https://stackoverflow.com/a/40285262/5879376
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.setComponent(new ComponentName("com.whatsapp","com.whatsapp.Conversation"));
sendIntent.putExtra("jid", PhoneNumberUtils.stripSeparators("YOUR_PHONE_NUMBER")+"#s.whatsapp.net");//phone number without "+" prefix
startActivity(sendIntent);
Update:
The aforementioned hack cannot be used to add any particular message, so here is the new approach. Pass the user mobile in international format here without any brackets, dashes or plus sign. Example: If the user is of India and his mobile number is 94xxxxxxxx , then international format will be 9194xxxxxxxx. Don't miss appending country code as a prefix in mobile number.
private fun sendMsg(mobile: String, msg: String){
try {
val packageManager = requireContext().packageManager
val i = Intent(Intent.ACTION_VIEW)
val url =
"https://wa.me/$mobile" + "?text=" + URLEncoder.encode(msg, "utf-8")
i.setPackage("com.whatsapp")
i.data = Uri.parse(url)
if (i.resolveActivity(packageManager) != null) {
requireContext().startActivity(i)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Note: This approach works only with contacts added in user's Whatsapp
account.
Whatsapp have its own API
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.setAction(Intent.ACTION_VIEW);
sendIntent.setPackage("com.whatsapp");
String url = "https://api.whatsapp.com/send?phone=" + "Phone with international format" + "&text=" + "your message";
sendIntent.setData(Uri.parse(url));
if(sendIntent.resolveActivity(context.getPackageManager()) != null){
startActivity(sendIntent);
}
Code updated check added for Activity is available or not.
See this documentation
Here am trying to send a text message in WhatsApp with another application.
Assume that we have a button, on button click ur calling below method.
sendTextMsgOnWhatsApp("+91 9876543210", "Hello, this my test message");
public void sendTextMsgOnWhatsApp(String sContactNo, String sMessage) {
String toNumber = sContactNo; // contains spaces, i.e., example +91 98765 43210
toNumber = toNumber.replace("+", "").replace(" ", "");
/*this method contactIdByPhoneNumber() will get unique id for given contact,
if this return's null then it means that you don't have any contact save with this mobile no.*/
String sContactId = contactIdByPhoneNumber(toNumber);
if (sContactId != null && sContactId.length() > 0) {
/*
* Once We get the contact id, we check whether contact has a registered with WhatsApp or not.
* this hasWhatsApp(hasWhatsApp) method will return null,
* if contact doesn't associate with whatsApp services.
* */
String sWhatsAppNo = hasWhatsApp(sContactId);
if (sWhatsAppNo != null && sWhatsAppNo.length() > 0) {
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.putExtra("jid", toNumber + "#s.whatsapp.net");
sendIntent.putExtra(Intent.EXTRA_TEXT, sMessage);
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setPackage("com.whatsapp");
sendIntent.setType("text/plain");
startActivity(sendIntent);
} else {
// this contact does not exist in any WhatsApp application
Toast.makeText(this, "Contact not found in WhatsApp !!", Toast.LENGTH_SHORT).show();
}
} else {
// this contact does not exist in your contact
Toast.makeText(this, "create contact for " + toNumber, Toast.LENGTH_SHORT).show();
}
}
private String contactIdByPhoneNumber(String phoneNumber) {
String contactId = null;
if (phoneNumber != null && phoneNumber.length() > 0) {
ContentResolver contentResolver = getContentResolver();
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
String[] projection = new String[]{ContactsContract.PhoneLookup._ID};
Cursor cursor = contentResolver.query(uri, projection, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
contactId = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
}
cursor.close();
}
}
return contactId;
}
public String hasWhatsApp(String contactID) {
String rowContactId = null;
boolean hasWhatsApp;
String[] projection = new String[]{ContactsContract.RawContacts._ID};
String selection = ContactsContract.RawContacts.CONTACT_ID + " = ? AND " + ContactsContract.RawContacts.ACCOUNT_TYPE + " = ?";
String[] selectionArgs = new String[]{contactID, "com.whatsapp"};
Cursor cursor = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, selectionArgs, null);
if (cursor != null) {
hasWhatsApp = cursor.moveToNext();
if (hasWhatsApp) {
rowContactId = cursor.getString(0);
}
cursor.close();
}
return rowContactId;
}
Add this below permission in AndroidManifest.xml file
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.INTERNET" />
This will first search for the specified contact and then open a chat window.
And if WhatsApp is not installed then try-catch block handle this.
String digits = "\\d+";
String mob_num = "987654321";
if (mob_num.matches(digits))
{
try {
//linking for whatsapp
Uri uri = Uri.parse("whatsapp://send?phone=+91" + mob_num);
Intent i = new Intent(Intent.ACTION_VIEW, uri);
startActivity(i);
}
catch (ActivityNotFoundException e){
e.printStackTrace();
//if you're in anonymous class pass context like "YourActivity.this"
Toast.makeText(this, "WhatsApp not installed.", Toast.LENGTH_SHORT).show();
}
}
This is the shortest way
String mPhoneNumber = "+972505555555";
mPhoneNumber = mPhoneNumber.replaceAll("+", "").replaceAll(" ", "").replaceAll("-","");
String mMessage = "Hello world";
String mSendToWhatsApp = "https://wa.me/" + mPhoneNumber + "?text="+mMessage;
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse(
mSendToWhatsApp
)));
See also the documentation of WhatsApp
try {
String text = "Hello, Admin sir";// Replace with your message.
String toNumber = "xxxxxxxxxxxx"; // Replace with mobile phone number without +Sign or leading zeros, but with country code
//Suppose your country is India and your phone number is “xxxxxxxxxx”, then you need to send “91xxxxxxxxxx”.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://api.whatsapp.com/send?phone=" + toNumber + "&text=" + text));
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=com.whatsapp")));
}
This is now possible through the WhatsApp Business API. Only businesses may apply to use it. This is the only way to directly send messages to phone numbers, without any human interaction.
Sending normal messages is free. It looks like you need to host a MySQL database and the WhatsApp Business Client on your server.
you can also select WhatsApp business vs WhatsApp
String url = "https://api.whatsapp.com/send?phone=" + phoneNumber + "&text=" +
URLEncoder.encode(messageText, "UTF-8");
if(useWhatsAppBusiness){
intent.setPackage("com.whatsapp.w4b");
} else {
intent.setPackage("com.whatsapp");
}
URLEncoder.encode(messageText, "UTF-8");
intent.setData(Uri.parse(url));
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent);
} else {
Toast.makeText(this, "WhatsApp application not found", Toast.LENGTH_SHORT).show();
}
try this, worked for me ! . Just use intent
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(whatsappUrl()));
startActivity(intent);
Build whatsapp url. add country code in whatsapp phone number https://countrycode.org/
public static String whatsappUrl(){
final String BASE_URL = "https://api.whatsapp.com/";
final String WHATSAPP_PHONE_NUMBER = "628123232323"; //'62' is country code for Indonesia
final String PARAM_PHONE_NUMBER = "phone";
final String PARAM_TEXT = "text";
final String TEXT_VALUE = "Hello, How are you ?";
String newUrl = BASE_URL + "send";
Uri builtUri = Uri.parse(newUrl).buildUpon()
.appendQueryParameter(PARAM_PHONE_NUMBER, WHATSAPP_PHONE_NUMBER)
.appendQueryParameter(PARAM_TEXT, TEXT_VALUE)
.build();
return buildUrl(builtUri).toString();
}
public static URL buildUrl(Uri myUri){
URL finalUrl = null;
try {
finalUrl = new URL(myUri.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
return finalUrl;
}
Send a text to specific contact programmatically (Whatsapp)
try {
val i = Intent(Intent.ACTION_VIEW)
val url = "https://api.whatsapp.com/send?phone=91XXXXXXXXXX&text=yourmessage"
i.setPackage("com.whatsapp")
i.data = Uri.parse(url)
startActivity(i)
} catch (e: Exception) {
e.printStackTrace()
val uri = Uri.parse("market://details?id=com.whatsapp")
val goToMarket = Intent(Intent.ACTION_VIEW, uri)
startActivity(goToMarket)
}
private void openWhatsApp() {
//without '+'
try {
Intent sendIntent = new Intent("android.intent.action.MAIN");
//sendIntent.setComponent(new ComponentName("com.whatsapp", "com.whatsapp.Conversation"));
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra("jid",whatsappId);
sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sendIntent.setPackage("com.whatsapp");
startActivity(sendIntent);
} catch(Exception e) {
Toast.makeText(this, "Error/n" + e.toString(), Toast.LENGTH_SHORT).show();
Log.e("Error",e+"") ; }
}
In Python, you can do it the same way we do it with mobile application
web.open('https://web.whatsapp.com/send?phone='+phone_no+'&text='+message)
This will prepopulate the text for given mobile number(Enter the phone_no as CountryCode and the number eg +918888888888)
Then using pyautogui you can press enter onto whatsapp.web
Working code :
def sendwhatmsg(phone_no, message, time_hour, time_min):
'''Sends whatsapp message to a particulal number at given time'''
if time_hour == 0:
time_hour = 24
callsec = (time_hour*3600)+(time_min*60)
curr = time.localtime()
currhr = curr.tm_hour
currmin = curr.tm_min
currsec = curr.tm_sec
currtotsec = (currhr*3600)+(currmin*60)+(currsec)
lefttm = callsec-currtotsec
if lefttm <= 0:
lefttm = 86400+lefttm
if lefttm < 60:
raise Exception("Call time must be greater than one minute")
else:
sleeptm = lefttm-60
time.sleep(sleeptm)
web.open('https://web.whatsapp.com/send?phone='+phone_no+'&text='+message)
time.sleep(60)
pg.press('enter')
I've taken this from this repository - Github repo
This code is implemented with Kotlin.
I have 2 versions:
1) For known contacts
private fun openWhatsApp(dato: WhatsApp) {
val isAppInstalled = appInstalledOrNot("com.whatsapp")
if (isAppInstalled) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://api.whatsapp.com/send?phone=${dato.whatsapp}"))
startActivity(intent)
} else {
// WhatsApp not installed show toast or dialog
}
}
private fun appInstalledOrNot(uri: String): Boolean {
val pm = requireActivity().packageManager
return try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
true
} catch (e: PackageManager.NameNotFoundException) {
false
}
}
In the case of being an unknown contact WhatsApp shows the following message
2) For unknown contacts
private fun openWhatsApp(dato: WhatsApp) {
val isAppInstalled = appInstalledOrNot("com.whatsapp")
if (isAppInstalled) {
val sendIntent = Intent("android.intent.action.MAIN")
sendIntent.setType("text/plain")
sendIntent.setComponent(ComponentName("com.whatsapp", "com.whatsapp.Conversation"))
sendIntent.putExtra("jid", PhoneNumberUtils.stripSeparators(dato.whatsapp) + "#s.whatsapp.net")
startActivity(sendIntent)
} else {
// WhatsApp not installed show toast or dialog
}
}
private fun appInstalledOrNot(uri: String): Boolean {
val pm = requireActivity().packageManager
return try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
true
} catch (e: PackageManager.NameNotFoundException) {
false
}
}
Use this function. Don't forget to save the WhatsApp Number on your mobile before sending trigger the function.
private void openWhatsApp() {
Uri uri = Uri.parse("smsto:"+ "12345");
Intent i = new Intent(Intent.ACTION_SENDTO,uri);
i.setPackage("com.whatsapp");
startActivity(i);
}
Update 2020
String number="+91 7*********";
String url="https://api.whatsapp.com/send?phone="+number + "&text=" + "Your text here";
Intent i=new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
Here is a way how to send message in WhatsApp in KOTLIN
private fun sendMessage(phone: String, message: String) {
val pm = requireActivity().packageManager
val i = Intent(Intent.ACTION_VIEW)
try {
val url = "https://api.whatsapp.com/send?phone=$phone&text=" + URLEncoder.encode(
message,
"UTF-8"
)
i.setPackage("com.whatsapp")
i.data = Uri.parse(url)
if (i.resolveActivity(pm) != null) {
context?.startActivity(i)
}
} catch (e: PackageManager.NameNotFoundException) {
Toast.makeText(requireContext(), "WhatsApp not Installed", Toast.LENGTH_SHORT).show()
}
}
The following will open up the Whatsapp conversation (with a contact) page and prefill it with the text provided. Note: This is not going to automatically send the text off to the Whatsapp servers. It will only open the conversation page. The user needs to explicitly press the "Send" button to actually have the text sent to the servers.
String phoneId = "+1415xxxyyyy"; // the (Whatsapp) phone number of contact
String text = "text to send";
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_TEXT, text);
sendIntent.putExtra("jid", phoneId);
sendIntent.setPackage("com.whatsapp");
startActivity(sendIntent);
Check this answer. Here your number start with "91**********".
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send."); sendIntent.putExtra("jid",PhoneNumberUtils.stripSeparators("91**********") + "#s.whatsapp.net");
sendIntent.setPackage("com.whatsapp");
startActivity(sendIntent);
This will first search for the specified contact and then open a chat window.
Note: phone_number and str are variables.
Uri mUri = Uri.parse("https://api.whatsapp.com/send?
phone=" + phone_no + "&text=" + str);
Intent mIntent = new Intent("android.intent.action.VIEW", mUri);
mIntent.setPackage("com.whatsapp");
startActivity(mIntent);
Bitmap bmp = null;
bmp = ((BitmapDrawable) tmpimg.getDrawable()).getBitmap();
Uri bmpUri = null;
try {
File file = new File(getBaseContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES), "share_image_" + System.currentTimeMillis() + ".jpg");
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
bmpUri = Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
String toNumber = "+919999999999";
toNumber = toNumber.replace("+", "").replace(" ", "");
Intent shareIntent =new Intent("android.intent.action.MAIN");
shareIntent.setAction(Intent.ACTION_SEND);
String ExtraText;
ExtraText = "Share Text";
shareIntent.putExtra(Intent.EXTRA_TEXT, ExtraText);
shareIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
shareIntent.setType("image/jpg");
shareIntent.setPackage("com.whatsapp");
shareIntent.putExtra("jid", toNumber + "#s.whatsapp.net");
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
startActivity(shareIntent);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(getBaseContext(), "Sharing tools have not been installed.", Toast.LENGTH_SHORT).show();
}
}
private void sendToContactUs() {
String phoneNo="+918000874386";
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.setAction(Intent.ACTION_VIEW);
sendIntent.setPackage("com.whatsapp");
String url = "https://api.whatsapp.com/send?phone=" + phoneNo + "&text=" + "Unique Code - "+CommonUtils.getMacAddress();
sendIntent.setDataAndType(Uri.parse(url),"text/plain");
if(sendIntent.resolveActivity(getPackageManager()) != null){
startActivity(sendIntent);
}else{
Toast.makeText(getApplicationContext(),"Please Install Whatsapp Massnger App in your Devices",Toast.LENGTH_LONG).show();
}
}
public void shareWhatsup(String text) {
String smsNumber = "91+" + "9879098469"; // E164 format without '+' sign
Intent intent = new Intent(Intent.ACTION_VIEW);
try {
String url = "https://api.whatsapp.com/send?phone=" + smsNumber + "&text=" + URLEncoder.encode(text, "UTF-8");
intent.setPackage("com.whatsapp");
intent.setData(Uri.parse(url));
} catch (Exception e) {
e.printStackTrace();
}
// intent.setAction(Intent.ACTION_SEND);
// intent.setType("image/jpeg");
// intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUriArray);
startActivity(intent);
}
Instead of biasing to share the content to whats app.
Following code is a generic code that will give a simple solution using "ShareCompact" that android opens the list of apps that supports the sharing the content.
Here I am sharing the data of mime-type text/plain.
String mimeType = "text/plain"
String Message = "Hi How are you doing?"
ShareCompact.IntentBuilder
.from(this)
.setType(mimeType)
.setText(Message)
.startChooser()
Whatsapp and most other apps that integrate into the Android core components (like Contacts) use a mime-type based intent to launch a certain Activity within the application. Whatsapp uses 3 separate mimetypes - text messages (vnd.android.cursor.item/vnd.com.whatsapp.profile), voip calls (vnd.android.cursor.item/vnd.com.whatsapp.voip.call) and video calls(vnd.android.cursor.item/vnd.com.whatsapp.video.call). For each of these mimetypes, a separate activity is mapped inside the Manifest of the application. For ex: the mimetype (...whatsapp.profile) maps to an Activity (com.whatsapp.Conversation). You can see these in detail if you dump out all the Data rows that maps to any Whatsapp Raw_Contact in your Contacts database.
This is also how the Android Contacts app shows 3 separate rows of user action inside a "Whatsapp contact", and clicking either of these rows launches a separate function inside Whatsapp.
To launch a Conversation (chat) Activity for a certain contact in Whatsapp, you need to fire an intent containing MIME_TYPE and DATA_URL. The mimetype points to the mimetype corresponding to your action as defined inside Whatsapp's Raw Contact in Contacts database. The DATA_URL is the URI of the Raw_Contact in the Android contacts database.
String whatsAppMimeType = Uri.parse("vnd.android.cursor.item").buildUpon()
.appendEncodedPath("vnd.com.whatsapp.profile").build().toString();
Uri uri = ContactsContract.RawContacts.CONTENT_URI.buildUpon()
.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, "com.whatsapp")
.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, "WhatsApp")
.build();
Cursor cursor = getContentResolver().query(uri, null, null, null);
if (cursor==null || cursor.getCount()==0) continue;
cursor.moveToNext();
int rawContactId = cursor.getInt(cursor.getColumnIndex(ContactsContract.RawContacts._ID));
cursor.close();
// now search for the Data row entry that matches the mimetype and also points to this RawContact
Cursor dataCursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.MIMETYPE + "=? AND " + ContactsContract.Data.RAW_CONTACT_ID + "=?",
new String[]{whatsAppMimeType, String.valueOf(rawContactId)}, null);
if (dataCursor==null || dataCursor.getCount()==0) continue;
dataCursor.moveToNext();
int dataRowId = dataCursor.getInt(dataCursor.getColumnIndex(ContactsContract.Data._ID));
Uri userRowUri = ContactsContract.Data.CONTENT_URI.buildUpon()
.appendPath(String.valueOf(dataRowId)).build();
// launch the whatsapp user chat activity
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(userRowUri, whatsAppMimeType);
startActivity(intent);
dataCursor.close();
This is the same way that all Contacts app use to launch a chat Activity for a Whatsapp contact. Inside this Activity, the application (Whatsapp) reads in the .getData() to get the DATA_URI which was passed to this Activity. The Android Contacts app uses a standard mechanism to use the URI of the Raw Contact in Whatsapp. Unfortunately, I am not aware of a way by which the .Conversation ativity in Whatsapp reads in any text / data information from the caller of the intent. This basically means that its possible (using a very standard technique) to launch a certain "user action" inside Whatsapp. Or for that matter, any similar app.

Sharing through email only in android using Intent

I want to send the photo by only email using Intent. I am using below code but its not opening only gmail but showing many share options.
Please help me to share the only gmail.
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("image/jpeg"); // put here your mime type
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(share, 0);
if(!resInfo.isEmpty()) {
Intent targetedShare = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
ArrayList<Uri> uris = new ArrayList<Uri>();
for (ResolveInfo info : resInfo) {
if(info.activityInfo.packageName.toLowerCase().contains("gmail") || info.activityInfo.name.toLowerCase().contains("gmail")) {
targetedShare.setType("image/jpeg"); // put here your mime type
targetedShare.putExtra(Intent.EXTRA_SUBJECT, "Amplimesh Photo");
targetedShare.putExtra(Intent.EXTRA_TEXT,"Attached the Quote");
//Fetching the Installed App and open the Gmail App.
for(int index = 0; index < productList.size(); index++) {
ByteArrayInputStream byteInputStream = new ByteArrayInputStream(productList.get(index).getOverlayBitmap());
Bitmap overLayBitmap = BitmapFactory.decodeStream(byteInputStream);
String fileName = SystemClock.currentThreadTimeMillis() + ".png";
//Save the bitmap to cache.
boolean isSaved = Helper.saveImageToExternalStorage(overLayBitmap, getApplicationContext(), fileName);
if(isSaved)
uris.add(Uri.fromFile(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/amplimesh/images/" + fileName)));
}
}
}
targetedShare.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
startActivityForResult(Intent.createChooser(targetedShare, "Sending multiple attachment"), 12345);
}
You can not get only gmail. but you can target some content type application.
try this
intent.setType("message/rfc822");
Try this:
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("image/jpeg");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] {""});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, EMAIL_SUBJECT);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, EMAIL_BODY);
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+fileName));
startActivity(Intent.createChooser(emailIntent, "Sharing Options"));
For me its working..
try Intent.ACTION_SENDTO
This is the method.
public void emailShare()
{
Intent emailIntent = new Intent(android.content.Intent.ACTION_SENDTO);
emailIntent.setType("image/jpeg");
//File bitmapFile = new File(Environment.getExternalStorageDirectory()+"DCIM/Camera/img.jpg");
//myUri = Uri.fromFile(bitmapFile);
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///mnt/sdcard/DCIM/Camera/img.jpg"));
emailIntent.setData(Uri.parse("mailto:"));
startActivityForResult(Intent.createChooser(emailIntent, "Complete action using:"),PICK_CONTACT_REQUEST);
}
Where startActivityForResult is to get the result back. and MESSAGE_RESULT is the result expected if mail sent successfully.
Catch the result on
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == MESSAGE_RESULT) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
Toast.makeText(getApplicationContext(), "E-Mail sent successfully", Toast.LENGTH_LONG).show();
}
}
}
Declare static final int MESSAGE_RESULT = 1; at the begining.
Hope it helps.
use Intent.ACTION_VIEW insted of Intent.ACTION_SEND
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.parse("mailto:?subject=" + "Subject" + "&body=" + "Body" + "&to=" + "email#mail.com");
intent.setData(data);
startActivity(Intent.createChooser(intent, "Choose app"));
or you can use:
startActivity(intent);
String shareImageLocation="Image file address";//Give file address here
Intent i = new Intent(Intent.ACTION_SEND_MULTIPLE);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL,
new String[] { "someone#someone.com" });
i.putExtra(Intent.EXTRA_SUBJECT, "Send photos");
i.putExtra(Intent.EXTRA_STREAM, shareImageLocation);
String bugReportBody = description;
i.putExtra(Intent.EXTRA_TEXT, bugReportBody);
ArrayList<Uri> uris = new ArrayList<Uri>();
File fileIn = new File(shareImageLocation);
uris.add(Uri.fromFile(fileIn));
i.putExtra(Intent.EXTRA_STREAM, uris);
try {
startActivityForResult(
Intent.createChooser(i, "Complete action using"),
SEND_EMAIL);
} catch (android.content.ActivityNotFoundException ex) {
}
Using only gmail app is not a good idea. Because there lot of phones which doesn't have gmail app installed. Try this code which will show all the app which can send email. I'm sure it won't show all the sharing app in your phone. But it will show some others apps which can handle any sharing intent. Like google drive.

Sending message through WhatsApp

Since I found some older posts, that tell that whatsapp doesn't support this, I was wondering if something had changed and if there is a way to open a whatsapp 'chat' with a number that I'm sending through an intent?
UPDATE
Please refer to https://faq.whatsapp.com/en/android/26000030/?category=5245251
WhatsApp's Click to Chat feature allows you to begin a chat with
someone without having their phone number saved in your phone's
address book. As long as you know this person’s phone number, you can
create a link that will allow you to start a chat with them.
Use: https://wa.me/15551234567
Don't use: https://wa.me/+001-(555)1234567
Example: https://wa.me/15551234567?text=I'm%20interested%20in%20your%20car%20for%20sale
Original answer
Here is the solution
public void onClickWhatsApp(View view) {
PackageManager pm=getPackageManager();
try {
Intent waIntent = new Intent(Intent.ACTION_SEND);
waIntent.setType("text/plain");
String text = "YOUR TEXT HERE";
PackageInfo info=pm.getPackageInfo("com.whatsapp", PackageManager.GET_META_DATA);
//Check if package exists or not. If not then code
//in catch block will be called
waIntent.setPackage("com.whatsapp");
waIntent.putExtra(Intent.EXTRA_TEXT, text);
startActivity(Intent.createChooser(waIntent, "Share with"));
} catch (NameNotFoundException e) {
Toast.makeText(this, "WhatsApp not Installed", Toast.LENGTH_SHORT)
.show();
}
}
Also see http://www.whatsapp.com/faq/en/android/28000012
With this code you can open the whatsapp chat with the given number.
void openWhatsappContact(String number) {
Uri uri = Uri.parse("smsto:" + number);
Intent i = new Intent(Intent.ACTION_SENDTO, uri);
i.setPackage("com.whatsapp");
startActivity(Intent.createChooser(i, ""));
}
Simple solution, try this.
String phoneNumberWithCountryCode = "+62820000000";
String message = "Hallo";
startActivity(
new Intent(Intent.ACTION_VIEW,
Uri.parse(
String.format("https://api.whatsapp.com/send?phone=%s&text=%s", phoneNumberWithCountryCode, message)
)
)
);
I found the following solution, first you'll need the whatsapp id:
Matching with reports from some other threads here and in other forums the login name I found was some sort of:
international area code without the 0's or + in the beginning + phone number without the first 0 + #s.whatsapp.net
For example if you live in the Netherlands and having the phone number 0612325032 it would be 31612325023#s.whatsapp.net -> +31 for the Netherlands without the 0's or + and the phone number without the 0.
public void sendWhatsAppMessageTo(String whatsappid) {
Cursor c = getSherlockActivity().getContentResolver().query(ContactsContract.Data.CONTENT_URI,
new String[] { ContactsContract.Contacts.Data._ID }, ContactsContract.Data.DATA1 + "=?",
new String[] { whatsappid }, null);
c.moveToFirst();
Intent whatsapp = new Intent(Intent.ACTION_VIEW, Uri.parse("content://com.android.contacts/data/" + c.getString(0)));
c.close();
if (whatsapp != null) {
startActivity(whatsapp);
} else {
Toast.makeText(this, "WhatsApp not Installed", Toast.LENGTH_SHORT)
.show();
//download for example after dialog
Uri uri = Uri.parse("market://details?id=com.whatsapp");
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
}
}
This should work whether Whatsapp is installed or not.
boolean isWhatsappInstalled = whatsappInstalledOrNot("com.whatsapp");
if (isWhatsappInstalled) {
Uri uri = Uri.parse("smsto:" + "98*********7")
Intent sendIntent = new Intent(Intent.ACTION_SENDTO, uri);
sendIntent.putExtra(Intent.EXTRA_TEXT, "Hai Good Morning");
sendIntent.setPackage("com.whatsapp");
startActivity(sendIntent);
} else {
Toast.makeText(this, "WhatsApp not Installed", Toast.LENGTH_SHORT).show();
Uri uri = Uri.parse("market://details?id=com.whatsapp");
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
startActivity(goToMarket);
}
private boolean whatsappInstalledOrNot(String uri) {
PackageManager pm = getPackageManager();
boolean app_installed = false;
try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
app_installed = true;
} catch (PackageManager.NameNotFoundException e) {
app_installed = false;
}
return app_installed;
}
Tested on Marshmallow S5 and it works!
Uri uri = Uri.parse("smsto:" + "phone number with country code");
Intent sendIntent = new Intent(Intent.ACTION_SENDTO, uri);
sendIntent.setPackage("com.whatsapp");
startActivity(sendIntent);
This will open a direct chat with a person, if whatsapp not installed this will throw exception, if phone number not known to whatsapp they will offer to send invite via sms or simple sms message
use this singleline code use to Sending message through WhatsApp
//NOTE : please use with country code first 2digits without plus signed
try {
String mobile = "911234567890";
String msg = "Its Working";
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://api.whatsapp.com/send?phone=" + mobile + "&text=" + msg)));
}catch (Exception e){
//whatsapp app not install
}
Here is the latest way to send a message via Whatsapp, even if the receiver's phone number is not in your Whatsapp chat or phone's Contacts list.
private fun openWhatsApp(number: String) {
try {
packageManager.getPackageInfo("com.whatsapp", PackageManager.GET_ACTIVITIES)
val intent = Intent(
Intent.ACTION_VIEW,
Uri.parse("https://wa.me/$number?text=I'm%20interested%20in%20your%20car%20for%20sale")
)
intent.setPackage("com.whatsapp")
startActivity(intent)
} catch (e: PackageManager.NameNotFoundException) {
Toast.makeText(
this,
"Whatsapp app not installed in your phone",
Toast.LENGTH_SHORT
).show()
e.printStackTrace()
}
}
intent.setPackage("com.whatsapp") will help you to avoid Open With chooser and open Whatsapp directly.
Importent Note: If You are ending in catch statement, even if Whatsapp is installed. Please add queries to manifest.xml as follows:
<queries>
<package android:name="com.whatsapp" />
</queries>
Please see this answer for more details.
To check if WhatsApp is installed in device and initiate "click to chat" in WhatsApp:
Kotlin:
try {
// Check if whatsapp is installed
context?.packageManager?.getPackageInfo("com.whatsapp", PackageManager.GET_META_DATA)
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://wa.me/$internationalPhoneNumber"))
startActivity(intent)
} catch (e: NameNotFoundException) {
Toast.makeText(context, "WhatsApp not Installed", Toast.LENGTH_SHORT).show()
}
Java:
try {
// Check if whatsapp is installed
getPackageManager().getPackageInfo("com.whatsapp", PackageManager.GET_META_DATA);
Intent intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://wa.me/" + internationalPhoneNumber));
startActivity(intent);
} catch (NameNotFoundException e) {
Toast.makeText(context, "WhatsApp not Installed", Toast.LENGTH_SHORT).show();
}
getPackageInfo() throws NameNotFoundException if WhatsApp is not installed.
The internationalPhoneNumber variable is used to access the phone number.
Reference:
https://faq.whatsapp.com/general/chats/how-to-use-click-to-chat?category=5245251
https://stackoverflow.com/a/2201999/9636037
https://stackoverflow.com/a/15931345/9636037
The following code is used by Google Now App and will NOT work for any other application.
I'm writing this post because it makes me angry, that WhatsApp does not allow any other developers to send messages directly except for Google.
And I want other freelance-developers to know, that this kind of cooperation is going on, while Google keeps talking about "open for anybody" and WhatsApp says they don't want to provide any access to developers.
Recently WhatsApp has added an Intent specially for Google Now, which should look like following:
Intent intent = new Intent("com.google.android.voicesearch.SEND_MESSAGE_TO_CONTACTS");
intent.setPackage("com.whatsapp");
intent.setComponent(new ComponentName("com.whatsapp", "com.whatsapp.VoiceMessagingActivity"));
intent.putExtra("com.google.android.voicesearch.extra.RECIPIENT_CONTACT_CHAT_ID", number);
intent.putExtra("android.intent.extra.TEXT", text);
intent.putExtra("search_action_token", ?????);
I could also find out that "search_action_token" is a PendingIntent
that contains an IBinder-Object, which is sent back to Google App and checked, if it was created by Google Now.
Otherwise WhatsApp will not accept the message.
Currently, the only official API that you may make a GET request to:
https://api.whatsapp.com/send?phone=919773207706&text=Hello
Anyways, there is a secret API program already being ran by WhatsApp
As the documentation says you can just use an URL like:
https://wa.me/15551234567
Where the last segment is the number in in E164 Format
Uri uri = Uri.parse("https://wa.me/15551234567");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
This is what worked for me :
Uri uri = Uri.parse("https://api.whatsapp.com/send?phone=" + "<number>" + "&text=" + "Hello WhatsApp!!");
Intent sendIntent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(sendIntent);
This works to me:
PackageManager pm = context.getPackageManager();
try {
pm.getPackageInfo("com.whatsapp", PackageManager.GET_ACTIVITIES);
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName,
ri.activityInfo.name));
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, element);
} catch (NameNotFoundException e) {
ToastHelper.MakeShortText("Whatsapp have not been installed.");
}
Use direct URL of whatsapp
String url = "https://api.whatsapp.com/send?phone="+number;
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
You'll want to use a URL in the following format...
https://api.whatsapp.com/send?text=text
Then you can have it send whatever text you'd like. You also have the option to specify a phone number...
https://api.whatsapp.com/send?text=text&phone=1234
What you CANNOT DO is use the following:
https://wa.me/send?text=text
You will get...
We couldn't find the page you were looking for
wa.me, though, will work if you supply both a phone number and text. But, for the most part, if you're trying to make a sharing link, you really don't want to indicate the phone number, because you want the user to select someone. In that event, if you don't supply the number and use wa.me as URL, all of your sharing links will fail. Please use app.whatsapp.com.
this is much lengthy but surly working.
enjoy your code:)
//method used to show IMs
private void show_custom_chooser(String value) {
List<ResolveInfo> list = null;
final Intent email = new Intent(Intent.ACTION_SEND);
email.setData(Uri.parse("sms:"));
email.putExtra(Intent.EXTRA_TEXT, "" + value);
email.setType("text/plain"); // vnd.android-dir/mms-sms
WindowManager.LayoutParams WMLP = dialogCustomChooser.getWindow()
.getAttributes();
WMLP.gravity = Gravity.CENTER;
dialogCustomChooser.getWindow().setAttributes(WMLP);
dialogCustomChooser.getWindow().setBackgroundDrawable(
new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialogCustomChooser.setCanceledOnTouchOutside(true);
dialogCustomChooser.setContentView(R.layout.about_dialog);
dialogCustomChooser.setCancelable(true);
ListView lvOfIms = (ListView) dialogCustomChooser
.findViewById(R.id.listView1);
PackageManager pm = getPackageManager();
List<ResolveInfo> launchables = pm.queryIntentActivities(email, 0);
// ////////////new
list = new ArrayList<ResolveInfo>();
for (int i = 0; i < launchables.size(); i++) {
String string = launchables.get(i).toString();
Log.d("heh", string);
//check only messangers
if (string.contains("whatsapp")) {
list.add(launchables.get(i));
}
}
Collections.sort(list, new ResolveInfo.DisplayNameComparator(pm));
int size = launchables.size();
adapter = new AppAdapter(pm, list, MainActivity.this);
lvOfIms.setAdapter(adapter);
lvOfIms.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
ResolveInfo launchable = adapter.getItem(position);
ActivityInfo activity = launchable.activityInfo;
ComponentName name = new ComponentName(
activity.applicationInfo.packageName, activity.name);
email.addCategory(Intent.CATEGORY_LAUNCHER);
email.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
email.setComponent(name);
startActivity(email);
dialogCustomChooser.dismiss();
}
});
dialogCustomChooser.show();
}
I'm really late here but I believe that nowadays we have shorter and better solutions to send messages through WhatsApp.
You can use the following to call the system picker, then choose which app you will use to share whatever you want.
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);
If you are really need to send through WhatsApp all you need to do is the following (You will skip the system picker)
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
// Put this line here
sendIntent.setPackage("com.whatsapp");
//
startActivity(sendIntent);
If you need more information you can find it here: WhatsApp FAQ
private fun sendWhatsappMessage(phoneNumber:String, text:String) {
val url = if (Intent().setPackage("com.whatsapp").resolveActivity(packageManager) != null) {
"whatsapp://send?text=Hello&phone=$phoneNumber"
} else {
"https://api.whatsapp.com/send?phone=$phoneNumber&text=$text"
}
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(browserIntent)
}
This is a much easier way to achieve this. This code checks if whatsapp is installed on the device. If it is installed, it bypasses the system picker and goes to the contact on whatsapp and prefields the text in the chat. If not installed it opens whatsapp link on your web browser.
Sending to WhatsApp Number that exist in your contact list.
Notice that we are using ACTION_SEND
Intent whatsappIntent = new Intent(Intent.ACTION_SEND);
whatsappIntent.setType("text/plain");
whatsappIntent.setPackage("com.whatsapp");
whatsappIntent.putExtra(Intent.EXTRA_TEXT, "SMS TEXT, TEXT THAT YOU NEED TO SEND");
try {
startActivityForResult(whatsappIntent, 100);
} catch (Exception e) {
Toast.makeText(YourActivity.this, "App is not installed", Toast.LENGTH_SHORT).show();
}
If Number doesn't exist in contact list. Use WhatsApp API.
String number = number_phone.getText().toString(); // I toke it from Dialog box
number = number.substring(1); // To remove 0 at the begging of number (Optional) but needed in my case
number = "962" + number; // Replace it with your country code
String url = "https://api.whatsapp.com/send?phone=" + number + "&text=" + Uri.parse("Text that you want to send to the current user");
Intent whatsappIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
whatsappIntent.setPackage("com.whatsapp");
whatsappIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(whatsappIntent);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(YourActivity.this, "App is not installed", Toast.LENGTH_SHORT).show();
}
Check this code,
public void share(String subject,String text) {
final Intent intent = new Intent(Intent.ACTION_SEND);
String score=1000;
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, score);
intent.putExtra(Intent.EXTRA_TEXT, text);
startActivity(Intent.createChooser(intent, getString(R.string.share)));
}
This works to me:
public static void shareWhatsApp(Activity appActivity, String texto) {
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(android.content.Intent.EXTRA_TEXT, texto);
PackageManager pm = appActivity.getApplicationContext().getPackageManager();
final List<ResolveInfo> matches = pm.queryIntentActivities(sendIntent, 0);
boolean temWhatsApp = false;
for (final ResolveInfo info : matches) {
if (info.activityInfo.packageName.startsWith("com.whatsapp")) {
final ComponentName name = new ComponentName(info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
sendIntent.addCategory(Intent.CATEGORY_LAUNCHER);
sendIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK);
sendIntent.setComponent(name);
temWhatsApp = true;
break;
}
}
if(temWhatsApp) {
//abre whatsapp
appActivity.startActivity(sendIntent);
} else {
//alerta - você deve ter o whatsapp instalado
Toast.makeText(appActivity, appActivity.getString(R.string.share_whatsapp), Toast.LENGTH_SHORT).show();
}
}
get the contact number whom you want to send the message and create uri for whatsapp, here c is a Cursor returning the selected contact.
Uri.parse("content://com.android.contacts/data/" + c.getString(0)));
i.setType("text/plain");
i.setPackage("com.whatsapp"); // so that only Whatsapp reacts and not the chooser
i.putExtra(Intent.EXTRA_SUBJECT, "Subject");
i.putExtra(Intent.EXTRA_TEXT, "I'm the body.");
startActivity(i);
From the documentation
To create your own link with a pre-filled message that will
automatically appear in the text field of a chat, use
https://wa.me/whatsappphonenumber/?text=urlencodedtext where
whatsappphonenumber is a full phone number in international format and
URL-encodedtext is the URL-encoded pre-filled message.
Example:https://wa.me/15551234567?text=I'm%20interested%20in%20your%20car%20for%20sale
Code example
val phoneNumber = "13492838472"
val text = "Hey, you know... I love StackOverflow :)"
val uri = Uri.parse("https://wa.me/$phoneNumber/?text=$text")
val sendIntent = Intent(Intent.ACTION_VIEW, uri)
startActivity(sendIntent)
This one worked finally for me in Kotlin:
private fun navigateToWhatsApp() {
try {
val url = "https://api.whatsapp.com/send?phone=+91${getString(R.string.contact)}"
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)).setPackage("com.whatsapp"))
} catch (e: Exception) {
showToast("Whatsapp app not installed in your device")
}
}
The following API can be used in c++ as shown in my article.
You need to define several constants:
//
#define    GroupAdmin                <YOUR GROUP ADMIN MOBILE PHONE>
#define GroupName                <YOUR GROUP NAME>
#define CLIENT_ID                <YOUR CLIENT ID>
#define CLIENT_SECRET            <YOUR CLIENT SECRET>
#define GROUP_API_SERVER        L"api.whatsmate.net"
#define GROUP_API_PATH          L"/v3/whatsapp/group/text/message/12"
#define IMAGE_SINGLE_API_URL    L"http://api.whatsmate.net/v3/whatsapp/group/image/message/12"
//
Then you connect to the API’s endpoint.
hOpenHandle = InternetOpen(_T("HTTP"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (hOpenHandle == NULL)
{
return false;
}
hConnectHandle = InternetConnect(hOpenHandle,
GROUP_API_SERVER,
INTERNET_DEFAULT_HTTP_PORT,
NULL, NULL, INTERNET_SERVICE_HTTP,
0, 1);
if (hConnectHandle == NULL)
{
InternetCloseHandle(hOpenHandle);
return false;
}
Then send both header and body and wait for the result that needs to be “OK”.
Step 1 - open an HTTP request:
const wchar_t *AcceptTypes[] = { _T("application/json"),NULL };
HINTERNET hRequest = HttpOpenRequest(hConnectHandle, _T("POST"), GROUP_API_PATH, NULL, NULL, AcceptTypes, 0, 0);
if (hRequest == NULL)
{
InternetCloseHandle(hConnectHandle);
InternetCloseHandle(hOpenHandle);
return false;
}
Step 2 - send the header:
std::wstring HeaderData;
HeaderData += _T("X-WM-CLIENT-ID: ");
HeaderData += _T(CLIENT_ID);
HeaderData += _T("\r\nX-WM-CLIENT-SECRET: ");
HeaderData += _T(CLIENT_SECRET);
HeaderData += _T("\r\n");
HttpAddRequestHeaders(hRequest, HeaderData.c_str(), HeaderData.size(), NULL);
Step 3 - send the message:
std::wstring WJsonData;
WJsonData += _T("{");
WJsonData += _T("\"group_admin\":\"");
WJsonData += groupAdmin;
WJsonData += _T("\",");
WJsonData += _T("\"group_name\":\"");
WJsonData += groupName;
WJsonData += _T("\",");
WJsonData += _T("\"message\":\"");
WJsonData += message;
WJsonData += _T("\"");
WJsonData += _T("}");
const std::string JsonData(WJsonData.begin(), WJsonData.end());
bResults = HttpSendRequest(hRequest, NULL, 0, (LPVOID)(JsonData.c_str()), JsonData.size());
Now just check the result:
TCHAR StatusText[BUFFER_LENGTH] = { 0 };
DWORD StatusTextLen = BUFFER_LENGTH;
HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_TEXT, &StatusText, &StatusTextLen, NULL);
bResults = (StatusTextLen && wcscmp(StatusText, L"OK")==FALSE);

Using Android Intent.ACTION_SEND for sending email

I'm using Intent.ACTION_SEND to send an email. However, when I call the intent it is showing choices to send a message, send an email, and also to send via bluetooth. I want it to only show choices to send an email. How can I do this?
[Solution for API LEVEL >=15]
I've finally succeded in sending email WITH attachments to ONLY email clients.
I write it here because it took me a lot of time and it may be usefull to others.
The problem is:
Intent.ACTION_SENDTO takes Data URI (so you can specify "mailto:"
schema) BUT it does not accept Intent:EXTRA_STREAM.
Intent.ACTION_SEND accepts Intent:EXTRA_STREAM (so you can add
attachment) BUT it takes only Type (not Data URI so you cannot
specify "mailto:" schema).
So Intent.ACTION_SEND lets the user choose from several Activities, even if you setType("message/rfc822"), because that App/Activities can manage all file types (tipically GDrive/Dropbox Apps) and so even email message files.
The solution is in the setSelector method.
With this method you can use Intent.ACTION_SENDTO to select the Activity, but then send the Intent.ACTION_SEND Intent.
Here my solution code (the attachment came from a FileProvider, but it could be any file):
{
Intent emailSelectorIntent = new Intent(Intent.ACTION_SENDTO);
emailSelectorIntent.setData(Uri.parse("mailto:"));
final Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"address#mail.com"});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
emailIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
emailIntent.setSelector( emailSelectorIntent );
Uri attachment = FileProvider.getUriForFile(this, "my_fileprovider", myFile);
emailIntent.putExtra(Intent.EXTRA_STREAM, attachment);
if( emailIntent.resolveActivity(getPackageManager()) != null )
startActivity(emailIntent);
}
I'm not taking credit for this answer but I believe it gives the best answer for this post.
It's a common misconception to use text/plain or text/html. This will trigger any application that can handle plain or HTML text files without any context, including Google Drive, Dropbox, Evernote and Skype.
Instead use a ACTION_SENDTO, providing the mailto: Uri
intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"));
You can then proceed using the chooser as suggested through the other answers.
Answered by #PaulLammertsma here
Android email chooser
Intent email = new Intent(android.content.Intent.ACTION_SEND);
email.setType("application/octet-stream");
EDIT:
You could try setting the type to "message/rfc822" as well.
try this...
#Ganapathy:try this code for display gmail
Intent gmail = new Intent(Intent.ACTION_VIEW);
gmail.setClassName("com.google.android.gm","com.google.android.gm.ComposeActivityGmail");
gmail.putExtra(Intent.EXTRA_EMAIL, new String[] { "jckdsilva#gmail.com" });
gmail.setData(Uri.parse("jckdsilva#gmail.com"));
gmail.putExtra(Intent.EXTRA_SUBJECT, "enter something");
gmail.setType("plain/text");
gmail.putExtra(Intent.EXTRA_TEXT, "hi android jack!");
startActivity(gmail);
This will help you.
On your button click :
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_EMAIL, new String[]{"youremail#yahoo.com"});
email.putExtra(Intent.EXTRA_SUBJECT, "subject");
email.putExtra(Intent.EXTRA_TEXT, "message");
email.setType("message/rfc822");
startActivity(Intent.createChooser(email, "Choose an Email client :"));
Using message/rfc822 type as pointed here: ACTION_SEND force sending with email solves the issue.
I had a similar problem with my app. I recently found this link form the official android developers site that really helps!
Common Intents: Email
TL;DR:
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:"));
Now, you will only be shown email clients!
You can add a Subject and Body by doing this:
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "Body" );
I notice, that this is an pretty old question but it is the first result when searching for a "Send mail" solution and all answers have a common problem:
Using Intent.ACTION_SEND and intent.setType("message/rfc822") will result in a chooser that not only shows mail apps but all apps that can handle any MIME type support by message/rfc822, e.g. .mhtml, .mht, .mime. Beside mail apps this could be Google Drive, Dropbox, Evernote, etc.
The only solution I found to limit the chooser to mail apps only is to use Intent.ACTION_SENDTO instead:
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto","address#example.com", null));
intent.putExtra(Intent.EXTRA_SUBJECT, "My Mail");
intent.putExtra(Intent.EXTRA_TEXT , "My Message");
try {
startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(MainActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
Thanks to the Open source developer, cketti for sharing this concise and neat solution. It's the only method that worked for me.
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.
First solution: try to be more specific in your Intent parameters. Add a message recipient for instance
emailIntent .putExtra(android.content.Intent.EXTRA_EMAIL, new String[] {"user#example.com"});
Second solution: use the package manager to find all applications capable of sending a message and select the only those you want to use.
Shout-out to ARLabs for posting the best solution on how to send an email on android. I just made a little update - an option to add multiple email attachements.
fun sendEmail(context: Context, recipients: List<String>?, subject: String?, body: String?, attachments: List<Uri>?) {
val emailIntent = Intent(Intent.ACTION_SEND_MULTIPLE)
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
emailIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
emailIntent.selector = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"))
recipients?.let {
val recipientsArray = arrayOfNulls<String>(recipients.size)
ArrayList(recipients).toArray(recipientsArray)
emailIntent.putExtra(Intent.EXTRA_EMAIL, recipientsArray)
}
subject?.let {
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject)
}
body?.let {
emailIntent.putExtra(Intent.EXTRA_TEXT, body)
}
if (attachments?.isNotEmpty() == true) {
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList(attachments))
}
try {
context.startActivity(emailIntent)
} catch (e: ActivityNotFoundException) {
// TODO handle "no app to handle action" error
}
}
This is a combination of Jack Dsilva and Jignesh Mayani solutions:
try
{
Intent gmailIntent = new Intent(Intent.ACTION_SEND);
gmailIntent.setType("text/html");
final PackageManager pm = _activity.getPackageManager();
final List<ResolveInfo> matches = pm.queryIntentActivities(gmailIntent, 0);
String gmailActivityClass = null;
for (final ResolveInfo info : matches)
{
if (info.activityInfo.packageName.equals("com.google.android.gm"))
{
gmailActivityClass = info.activityInfo.name;
if (gmailActivityClass != null && !gmailActivityClass.isEmpty())
{
break;
}
}
}
gmailIntent.setClassName("com.google.android.gm", gmailActivityClass);
gmailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { "yourmail#gmail.com" });
gmailIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
gmailIntent.putExtra(Intent.EXTRA_CC, "cc#gmail.com"); // if necessary
gmailIntent.putExtra(Intent.EXTRA_TEXT, "Email message");
gmailIntent.setData(Uri.parse("yourmail#gmail.com"));
this._activity.startActivity(gmailIntent);
}
catch (Exception e)
{
Intent i = new Intent(Intent.ACTION_SEND);
i.putExtra(Intent.EXTRA_EMAIL, new String[] { "yourmail#gmail.com" });
i.putExtra(Intent.EXTRA_SUBJECT, "Subject");
i.putExtra(Intent.EXTRA_CC, "cc#gmail.com"); // if necessary
i.putExtra(Intent.EXTRA_TEXT, "Email message");
i.setType("plain/text");
this._activity.startActivity(i);
}
So, at first it will try to open gmail app and in case a user doesn't have it then the second approach will be implemented.
Best code to restrict it to only send an email. set this type to only send an email. i.setType("message/rfc822");
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL , new String[]{"skapis1#outlook.com"});
i.putExtra(Intent.EXTRA_SUBJECT, "subject of email");
i.putExtra(Intent.EXTRA_TEXT , "body of email");
try {
startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(Firstclass.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
This saved my day. It sends composed text message directly to gmail app:
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto","togmail.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Report message");
emailIntent.putExtra(Intent.EXTRA_TEXT, edt_msg.getText().toString());
startActivity(Intent.createChooser(emailIntent, "Send email..."));
This will open only the Email app installed in your android phone.
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:"));
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"example#gmail.com"});
intent.putExtra(Intent.EXTRA_SUBJECT, "email subject");
intent.putExtra(Intent.EXTRA_TEXT, "message body");
try {
startActivity(Intent.createChooser(intent, "send mail"));
} catch (ActivityNotFoundException ex) {
Toast.makeText(this, "No mail app found!!!", Toast.LENGTH_SHORT);
} catch (Exception ex) {
Toast.makeText(this, "Unexpected Error!!!", Toast.LENGTH_SHORT);
}
public class MainActivity extends AppCompatActivity {
private EditText edt_email;
private Button btn_send;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edt_email = (EditText) findViewById(R.id.edt_email);
btn_send = (Button) findViewById(R.id.btn_send);
btn_send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_SEND );
intent.putExtra(Intent.EXTRA_EMAIL , new String[]{"sanaebadi97#gmail.com"});
intent.putExtra(Intent.EXTRA_SUBJECT , "subject");
intent.putExtra(Intent.EXTRA_TEXT , "My Email Content");
intent.setType("message/rfc822");
startActivity(Intent.createChooser(intent , "Choose Your Account : "));
}
});
}
}
try with ACTION_VIEW not ACTION_SENDTO , ACTION_VIEW will makes system calls only to Email Apps
Intent emailIntent = new Intent(Intent.ACTION_VIEW);

How to send emails from my Android application?

I am developing an application in Android. I don't know how to send an email from the application?
The best (and easiest) way is to use an Intent:
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL , new String[]{"recipient#example.com"});
i.putExtra(Intent.EXTRA_SUBJECT, "subject of email");
i.putExtra(Intent.EXTRA_TEXT , "body of email");
try {
startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(MyActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
Otherwise you'll have to write your own client.
Use .setType("message/rfc822") or the chooser will show you all of the (many) applications that support the send intent.
I've been using this since long time ago and it seems good, no non-email apps showing up. Just another way to send a send email intent:
Intent intent = new Intent(Intent.ACTION_SENDTO); // it's not ACTION_SEND
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject of email");
intent.putExtra(Intent.EXTRA_TEXT, "Body of email");
intent.setData(Uri.parse("mailto:default#example.com")); // or just "mailto:" for blank
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // this will make such that when user returns to your app, your app is displayed, instead of the email app.
startActivity(intent);
I was using something along the lines of the currently accepted answer in order to send emails with an attached binary error log file. GMail and K-9 send it just fine and it also arrives fine on my mail server. The only problem was my mail client of choice Thunderbird which had troubles with opening / saving the attached log file. In fact it simply didn't save the file at all without complaining.
I took a look at one of these mail's source codes and noticed that the log file attachment had (understandably) the mime type message/rfc822. Of course that attachment is not an attached email. But Thunderbird cannot cope with that tiny error gracefully. So that was kind of a bummer.
After a bit of research and experimenting I came up with the following solution:
public Intent createEmailOnlyChooserIntent(Intent source,
CharSequence chooserTitle) {
Stack<Intent> intents = new Stack<Intent>();
Intent i = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto",
"info#example.com", null));
List<ResolveInfo> activities = getPackageManager()
.queryIntentActivities(i, 0);
for(ResolveInfo ri : activities) {
Intent target = new Intent(source);
target.setPackage(ri.activityInfo.packageName);
intents.add(target);
}
if(!intents.isEmpty()) {
Intent chooserIntent = Intent.createChooser(intents.remove(0),
chooserTitle);
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
intents.toArray(new Parcelable[intents.size()]));
return chooserIntent;
} else {
return Intent.createChooser(source, chooserTitle);
}
}
It can be used as follows:
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("*/*");
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(crashLogFile));
i.putExtra(Intent.EXTRA_EMAIL, new String[] {
ANDROID_SUPPORT_EMAIL
});
i.putExtra(Intent.EXTRA_SUBJECT, "Crash report");
i.putExtra(Intent.EXTRA_TEXT, "Some crash report details");
startActivity(createEmailOnlyChooserIntent(i, "Send via email"));
As you can see, the createEmailOnlyChooserIntent method can be easily fed with the correct intent and the correct mime type.
It then goes through the list of available activities that respond to an ACTION_SENDTO mailto protocol intent (which are email apps only) and constructs a chooser based on that list of activities and the original ACTION_SEND intent with the correct mime type.
Another advantage is that Skype is not listed anymore (which happens to respond to the rfc822 mime type).
To JUST LET EMAIL APPS to resolve your intent you need to specify ACTION_SENDTO as Action and mailto as Data.
private void sendEmail(){
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto:" + "recipient#example.com")); // You can use "mailto:" if you don't know the address beforehand.
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "My email's subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "My email's body");
try {
startActivity(Intent.createChooser(emailIntent, "Send email using..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(Activity.this, "No email clients installed.", Toast.LENGTH_SHORT).show();
}
}
The solution to this is simple: the android documentation explains it.
(https://developer.android.com/guide/components/intents-common.html#Email)
The most important is the flag: it is ACTION_SENDTO, and not ACTION_SEND
The other important line is
intent.setData(Uri.parse("mailto:")); ***// only email apps should handle this***
By the way, if you send an empty Extra, the if() at the end won't work and the app won't launch the email client.
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);
}
}
The strategy of using .setType("message/rfc822") or ACTION_SEND seems to also match apps that aren't email clients, such as Android Beam and Bluetooth.
Using ACTION_SENDTO and a mailto: URI seems to work perfectly, and is recommended in the developer documentation. However, if you do this on the official emulators and there aren't any email accounts set up (or there aren't any mail clients), you get the following error:
Unsupported action
That action is not currently supported.
As shown below:
It turns out that the emulators resolve the intent to an activity called com.android.fallback.Fallback, which displays the above message. Apparently this is by design.
If you want your app to circumvent this so it also works correctly on the official emulators, you can check for it before trying to send the email:
private void sendEmail() {
Intent intent = new Intent(Intent.ACTION_SENDTO)
.setData(new Uri.Builder().scheme("mailto").build())
.putExtra(Intent.EXTRA_EMAIL, new String[]{ "John Smith <johnsmith#yourdomain.com>" })
.putExtra(Intent.EXTRA_SUBJECT, "Email subject")
.putExtra(Intent.EXTRA_TEXT, "Email body")
;
ComponentName emailApp = intent.resolveActivity(getPackageManager());
ComponentName unsupportedAction = ComponentName.unflattenFromString("com.android.fallback/.Fallback");
if (emailApp != null && !emailApp.equals(unsupportedAction))
try {
// Needed to customise the chooser dialog title since it might default to "Share with"
// Note that the chooser will still be skipped if only one app is matched
Intent chooser = Intent.createChooser(intent, "Send email with");
startActivity(chooser);
return;
}
catch (ActivityNotFoundException ignored) {
}
Toast
.makeText(this, "Couldn't find an email app and account", Toast.LENGTH_LONG)
.show();
}
Find more info in the developer documentation.
Sending email can be done with Intents which will require no configuration. But then it will require user interaction and the layout will be a bit restricted.
Build and sending a more complex email without user interaction entails building your own client. The first thing is that the Sun Java API for email are unavailable. I have had success leveraging the Apache Mime4j library to build email. All based on the docs at nilvec.
Here is the sample working code which opens mail application in android device and auto-filled with To address and Subject in the composing mail.
protected void sendEmail() {
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:feedback#gmail.com"));
intent.putExtra(Intent.EXTRA_SUBJECT, "Feedback");
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
I use the below code in my apps. This shows exactly email client apps, such as Gmail.
Intent contactIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", getString(R.string.email_to), null));
contactIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.email_subject));
startActivity(Intent.createChooser(contactIntent, getString(R.string.email_chooser)));
This will show you only the email clients (as well as PayPal for some unknown reason)
public void composeEmail() {
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:"));
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"hi#example.com"});
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "Body");
try {
startActivity(Intent.createChooser(intent, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(MainActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
}
This is how I did it. Nice and simple.
String emailUrl = "mailto:email#example.com?subject=Subject Text&body=Body Text";
Intent request = new Intent(Intent.ACTION_VIEW);
request.setData(Uri.parse(emailUrl));
startActivity(request);
I used this code to send mail by launching default mail app compose section directly.
Intent i = new Intent(Intent.ACTION_SENDTO);
i.setType("message/rfc822");
i.setData(Uri.parse("mailto:"));
i.putExtra(Intent.EXTRA_EMAIL , new String[]{"test#gmail.com"});
i.putExtra(Intent.EXTRA_SUBJECT, "Subject");
i.putExtra(Intent.EXTRA_TEXT , "body of email");
try {
startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
This function first direct intent gmail for sending email, if gmail is not found then promote intent chooser. I used this function in many commercial app and it's working fine. Hope it will help you:
public static void sentEmail(Context mContext, String[] addresses, String subject, String body) {
try {
Intent sendIntentGmail = new Intent(Intent.ACTION_VIEW);
sendIntentGmail.setType("plain/text");
sendIntentGmail.setData(Uri.parse(TextUtils.join(",", addresses)));
sendIntentGmail.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail");
sendIntentGmail.putExtra(Intent.EXTRA_EMAIL, addresses);
if (subject != null) sendIntentGmail.putExtra(Intent.EXTRA_SUBJECT, subject);
if (body != null) sendIntentGmail.putExtra(Intent.EXTRA_TEXT, body);
mContext.startActivity(sendIntentGmail);
} catch (Exception e) {
//When Gmail App is not installed or disable
Intent sendIntentIfGmailFail = new Intent(Intent.ACTION_SEND);
sendIntentIfGmailFail.setType("*/*");
sendIntentIfGmailFail.putExtra(Intent.EXTRA_EMAIL, addresses);
if (subject != null) sendIntentIfGmailFail.putExtra(Intent.EXTRA_SUBJECT, subject);
if (body != null) sendIntentIfGmailFail.putExtra(Intent.EXTRA_TEXT, body);
if (sendIntentIfGmailFail.resolveActivity(mContext.getPackageManager()) != null) {
mContext.startActivity(sendIntentIfGmailFail);
}
}
}
This is the most clean way of sending email on Android.
val intent = Intent(Intent.ACTION_SENDTO).apply {
data = Uri.parse("mailto:")
putExtra(Intent.EXTRA_EMAIL, arrayOf("email#example.com"))
putExtra(Intent.EXTRA_SUBJECT, "Subject")
putExtra(Intent.EXTRA_TEXT, "Email body")
}
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
You also need to specify in your manifest (outside your application tag) the query for applications that handle email (mailto)
<queries>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
</intent>
</queries>
If you need to send HTML text in the email body, please replace the "Email body" with your email string, something like this (please beware that Html.fromHtml maybe deprecated this was only for show you how to do it)
Html.fromHtml(
StringBuilder().append("<b>Hello world</b>").toString()
)
simple try this one
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonSend = (Button) findViewById(R.id.buttonSend);
textTo = (EditText) findViewById(R.id.editTextTo);
textSubject = (EditText) findViewById(R.id.editTextSubject);
textMessage = (EditText) findViewById(R.id.editTextMessage);
buttonSend.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String to = textTo.getText().toString();
String subject = textSubject.getText().toString();
String message = textMessage.getText().toString();
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_EMAIL, new String[] { to });
// email.putExtra(Intent.EXTRA_CC, new String[]{ to});
// email.putExtra(Intent.EXTRA_BCC, new String[]{to});
email.putExtra(Intent.EXTRA_SUBJECT, subject);
email.putExtra(Intent.EXTRA_TEXT, message);
// need this to prompts email client only
email.setType("message/rfc822");
startActivity(Intent.createChooser(email, "Choose an Email client :"));
}
});
}
Other solution can be
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emailIntent.setType("plain/text");
emailIntent.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"someone#gmail.com"});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Yo");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Hi");
startActivity(emailIntent);
Assuming most of the android device has GMail app already installed.
Use this for send email...
boolean success = EmailIntentBuilder.from(activity)
.to("support#example.org")
.cc("developer#example.org")
.subject("Error report")
.body(buildErrorReport())
.start();
use build gradle :
compile 'de.cketti.mailto:email-intent-builder:1.0.0'
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto","ebgsoldier#gmail.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Forgot Password");
emailIntent.putExtra(Intent.EXTRA_TEXT, "this is a text ");
startActivity(Intent.createChooser(emailIntent, "Send email..."));
This method work for me. It open Gmail app (if installed) and set mailto.
public void openGmail(Activity activity) {
Intent emailIntent = new Intent(Intent.ACTION_VIEW);
emailIntent.setType("text/plain");
emailIntent.setType("message/rfc822");
emailIntent.setData(Uri.parse("mailto:"+activity.getString(R.string.mail_to)));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, activity.getString(R.string.app_name) + " - info ");
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);
}
/**
* Will start the chosen Email app
*
* #param context current component context.
* #param emails Emails you would like to send to.
* #param subject The subject that will be used in the Email app.
* #param forceGmail True - if you want to open Gmail app, False otherwise. If the Gmail
* app is not installed on this device a chooser will be shown.
*/
public static void sendEmail(Context context, String[] emails, String subject, boolean forceGmail) {
Intent i = new Intent(Intent.ACTION_SENDTO);
i.setData(Uri.parse("mailto:"));
i.putExtra(Intent.EXTRA_EMAIL, emails);
i.putExtra(Intent.EXTRA_SUBJECT, subject);
if (forceGmail && isPackageInstalled(context, "com.google.android.gm")) {
i.setPackage("com.google.android.gm");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
} else {
try {
context.startActivity(Intent.createChooser(i, "Send mail..."));
} catch (ActivityNotFoundException e) {
Toast.makeText(context, "No email app is installed on your device...", Toast.LENGTH_SHORT).show();
}
}
}
/**
* Check if the given app is installed on this devuice.
*
* #param context current component context.
* #param packageName The package name you would like to check.
* #return True if this package exist, otherwise False.
*/
public static boolean isPackageInstalled(#NonNull Context context, #NonNull String packageName) {
PackageManager pm = context.getPackageManager();
if (pm != null) {
try {
pm.getPackageInfo(packageName, 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
return false;
}
Try this:
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
}
The above code will open the users favourite email client prefilled with the email ready to send.
Source
The code below works on Android 10 devices and higher. It also sets the subject, body and recipient(To).
val uri = Uri.parse("mailto:$EMAIL")
.buildUpon()
.appendQueryParameter("subject", "App Feedback")
.appendQueryParameter("body", "Body Text")
.appendQueryParameter("to", EMAIL)
.build()
val emailIntent = Intent(Intent.ACTION_SENDTO, uri)
startActivity(Intent.createChooser(emailIntent, "Select app"))
Kotlin version which only shows Email clients (no contacts etc.):
with(Intent(Intent.ACTION_SEND)) {
type = "message/rfc822"
data = Uri.parse("mailto:")
putExtra(Intent.EXTRA_EMAIL, arrayOf("user#example.com"))
putExtra(Intent.EXTRA_SUBJECT,"YOUR SUBJECT")
putExtra(Intent.EXTRA_TEXT, "YOUR BODY")
try {
startActivity(Intent.createChooser(this, "Send Email with"))
} catch (ex: ActivityNotFoundException) {
// No email clients found, might show Toast here
}
}
import androidx.core.app.ShareCompat
import androidx.core.content.IntentCompat
ShareCompat.IntentBuilder(this)
.setType("message/rfc822")
.setEmailTo(arrayOf(email))
.setStream(uri)
.setSubject(subject)
.setText(message + emailMessage)
.startChooser()
Filtering for 'real' E-Mail Apps is still an issue today. As many people mentioned above, other apps nowadays also report to support the mime-type "message/rfc822". Therefore, this mime-type is not suitable any more to filter for a real E-Mail App.
If you want to send a simple text mail, it is enough to use the the ACTION_SENDTO intent action with the appropriate data type like so:
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:"));
intent.putExtra(Intent.EXTRA_EMAIL, recipients);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, text);
Intent chooser = Intent.createChooser(intent, "Send Mail");
context.startActivity(chooser);
This will filter all available apps for those that support the 'mailto' protocol, which is much more suitable for the purpose of sending an E-mail.
But sadly things become complicated, if you want to send a mail with (multiple) attachments. The ACTION_SENDTO action does not support the EXTRA_STREAM extra on the intent. If you want to use that, you must use the ACTION_SEND_MULTIPLE action, which does not work together with the the data type Uri.parse("mailto:").
For now I found a solution, which consists of the following steps:
Declare that your App wants to query Apps on the device, that support the mailto protocol (important for all Apps since Android 11)
Actually query all Apps, that support the mailto protocol
For each supporting App: Build the intent that you actually want to launch, aiming for that single App
Build the App chooser and launch it
And this is how it looks in code:
Add this to the AndroidManifest:
<queries>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
</intent>
</queries>
This is the Java code:
/* Query all Apps that support the 'mailto' protocol */
PackageManager pm = context.getPackageManager();
Intent emailCheckerIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"));
List<ResolveInfo> emailApps = pm.queryIntentActivities(emailCheckerIntent, PackageManager.MATCH_DEFAULT_ONLY);
/* For each supporting App: Build an intent with the desired values */
List<Intent> intentList = new ArrayList<>();
for (ResolveInfo resolveInfo : emailApps) {
String packageName = resolveInfo.activityInfo.packageName;
Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
intent.setPackage(packageName);
intent.setComponent(new ComponentName(packageName, resolveInfo.activityInfo.name));
intent.putExtra(Intent.EXTRA_EMAIL, recipients);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, text);
intent.putExtra(Intent.EXTRA_STREAM, attachmentUris);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //IMPORTANT to give the E-Mail App access to your attached files
intentList.add(intent);
}
/* Create a chooser consisting of the queried apps only */
Intent chooser = Intent.createChooser(intentList.remove(intentList.size() - 1), "Send Mail");
Intent[] extraIntents = intentList.toArray(new Intent[0]);
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
context.startActivity(chooser);
Note: If the itentList only has one item, Android will automatically skip the chooser and run the only App automatically.

Categories

Resources