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);
Related
I tried so many solution but still no success in sending messages to particular whatsapp contact in my app. Here is my code :
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_TEXT, "Hey");
sendIntent.putExtra("jid", PhoneNumberUtils.stripSeparators(smsNumber) + "#s.whatsapp.net");
sendIntent.setPackage("com.whatsapp");
mContext.startActivity(sendIntent);
It is just opening particular contact chat window as new conversation with no contact name, profile pic and old conversion.
Please help me to solve this. Also attaching screenshot.
I think you want like this.
private void openWhatsApp() {
String text = message.getText().toString();
if(whatsappInstalledOrNot("com.whatsapp")){
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("whatsapp://send?text="+text+"&phone="+mobileNumber.getText().toString()));
startActivity(browserIntent);
}else {
Toast.makeText(this, "WhatsApp not Installed", Toast.LENGTH_SHORT)
.show();
}
}
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;
}
Hope this will help.
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.setComponent(new ComponentName("com.whatsapp","com.whatsapp.Conversation"));
sendIntent.putExtra(Intent.EXTRA_TEXT, "Hey");
sendIntent.putExtra("jid", PhoneNumberUtils.stripSeparators("91xxxx008686")+"#s.whatsapp.net");
//phone number without "+" prefix (countrycode & contact number without '+')
startActivity(sendIntent);
You have missed the set component part which retrieves old conversation from 'Conversation' class.
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.
Is there a way to programically open email client, without a need to forcing message send? I just want the app to let user open his email client for email checking purposes :)
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("message/rfc822");
startActivity(Intent.createChooser(intent, ""));
This code works but it forces user to send a new message.
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_APP_EMAIL);
startActivity(intent);
startActivity(Intent.createChooser(intent, getString(R.string.ChoseEmailClient)));
That kinda worked. But it opend Gmail for me, even since I have other email clients
This code will show a dialog with a list of email clients. Clicking one will launch the application:
try {
List<String> emailClientNames = new ArrayList<String>();
final List<String> emailClientPackageNames = new ArrayList<String>();
// finding list of email clients that support send email
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto", "abc#gmail.com", null));
PackageManager pkgManager = AppController.getContext().getPackageManager();
List<ResolveInfo> packages = pkgManager.queryIntentActivities(intent, 0);
if (!packages.isEmpty()) {
for (ResolveInfo resolveInfo : packages) {
// finding the package name
String packageName = resolveInfo.activityInfo.packageName;
emailClientNames.add(resolveInfo.loadLabel(getPackageManager()).toString());
emailClientPackageNames.add(packageName);
}
// a selection dialog for the email clients
AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);
builder.setTitle("Select email client");
builder.setItems(emailClientNames.toArray(new String[]{}), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// on click we launch the right package
Intent intent = getPackageManager().getLaunchIntentForPackage(emailClientPackageNames.get(which));
startActivity(intent);
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
} catch (ActivityNotFoundException e) {
// Show error message
}
In Kotlin, but this version creates a chooser for user to pick which email app to use. You basically do what Oved does in his answer, except create an actual chooser using LabeledIntent.
fun emailAppIntent(): Intent? {
val emailIntent = Intent(Intent.ACTION_VIEW, Uri.parse("mailto:"))
val packageManager = appLaunchContext.packageManager
val activitiesHandlingEmails = packageManager.queryIntentActivities(emailIntent, 0)
if (activitiesHandlingEmails.isNotEmpty()) {
// use the first email package to create the chooserIntent
val firstEmailPackageName = activitiesHandlingEmails.first().activityInfo.packageName
val firstEmailInboxIntent = packageManager.getLaunchIntentForPackage(firstEmailPackageName)
val emailAppChooserIntent = Intent.createChooser(firstEmailInboxIntent, "")
// created UI for other email packages and add them to the chooser
val emailInboxIntents = mutableListOf<LabeledIntent>()
for (i in 1 until activitiesHandlingEmails.size) {
val activityHandlingEmail = activitiesHandlingEmails[i]
val packageName = activityHandlingEmail.activityInfo.packageName
val intent = packageManager.getLaunchIntentForPackage(packageName)
emailInboxIntents.add(
LabeledIntent(
intent,
packageName,
activityHandlingEmail.loadLabel(packageManager),
activityHandlingEmail.icon
)
)
}
val extraEmailInboxIntents = emailInboxIntents.toTypedArray()
return emailAppChooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraEmailInboxIntents)
} else {
return null
}
}
.. then later call it with
val emailChooserIntent = emailAppIntent()
if (emailChooserIntent != null) {
startActivity(emailAppIntent())
}
or handle null however you want.
I think you should replace Intent.ACTION_SEND to Intent.ACTION_VIEW, i am sure this will work as this will prompt with list of application which support MIME type "message/rfc822" so it will include your default email client in your device other than gmail app.
How about this code:
final Intent emailLauncher = new Intent(Intent.ACTION_VIEW);
emailLauncher.setType("message/rfc822");
try{
startActivity(emailLauncher);
}catch(ActivityNotFoundException e){
}
A bit more modern solution in Kotlin
fun tryVerifyMail() {
try {
val intents: List<Intent> = (packageManager.queryIntentActivities(Intent(
Intent.ACTION_SENDTO, Uri.fromParts(
"mailto", "lowhillgamesoy#gmail.com", null
)
), 0) + packageManager.queryIntentActivities(Intent(Intent.ACTION_VIEW).also {
it.type = "message/rfc822"
}, 0)).mapNotNull {
it.activityInfo.packageName
}.toSet().mapNotNull {
packageManager.getLaunchIntentForPackage(it)
}
if(intents.size > 0) {
startActivityForResult(Intent.createChooser(intents.first(), getString(R.string.verify_mail)).also {
if(intents.size > 1) {
it.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.subList(1, intents.size - 1).toTypedArray())
}
}, OPEN_MAIL_REQUEST_CODE)
} else {
Toast.makeText(this, "Verify your e-mail by clicking the link in your e-mail inbox.", Toast.LENGTH_LONG).show()
}
} catch (e: ActivityNotFoundException) {
// Show error message
e.printStackTrace()
}
}
This also picks both mail clients only supporting ACTION_SEND and ACTION_VIEW and removes duplicates.
I'm developing an Android app and am interested to know how you can update the app user's status from within the app using Android's share intents.
Having looked through Facebook's SDK it appears that this is easy enough to do, however I'm keen to allow the user to do it via the regular Share Intent pop up window? seen here:
I have tried the usual share intent code, however this no longer appears to work for Facebook.
public void invokeShare(Activity activity, String quote, String credit) {
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, activity.getString(R.string.share_subject));
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Example text");
activity.startActivity(Intent.createChooser(shareIntent, activity.getString(R.string.share_title)));
}
UPDATE:
Having done more digging, it looks as though it's a bug with Facebook's app that has yet to be resolved! (facebook bug) For the mean time it looks like I'm just going to have to put up with the negative "Sharing doesn't work!!!" reviews. Cheers Facebook :*(
Apparently Facebook no longer (as of 2014) allows you to customise the sharing screen, no matter if you are just opening sharer.php URL or using Android intents in more specialised ways. See for example these answers:
"Sharer.php no longer allows you to customize."
"You need to use Facebook Android SDK or Easy Facebook Android SDK to share."
Anyway, using plain Intents, you can still share a URL, but not any default text with it, as billynomates commented. (Also, if you have no URL to share, just launching Facebook app with empty "Write Post" (i.e. status update) dialog is equally easy; use the code below but leave out EXTRA_TEXT.)
Here's the best solution I've found that does not involve using any Facebook SDKs.
This code opens the official Facebook app directly if it's installed, and otherwise falls back to opening sharer.php in a browser. (Most of the other solutions in this question bring up a huge "Complete action using…" dialog which isn't optimal at all!)
String urlToShare = "https://stackoverflow.com/questions/7545254";
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
// intent.putExtra(Intent.EXTRA_SUBJECT, "Foo bar"); // NB: has no effect!
intent.putExtra(Intent.EXTRA_TEXT, urlToShare);
// See if official Facebook app is found
boolean facebookAppFound = false;
List<ResolveInfo> matches = getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo info : matches) {
if (info.activityInfo.packageName.toLowerCase().startsWith("com.facebook.katana")) {
intent.setPackage(info.activityInfo.packageName);
facebookAppFound = true;
break;
}
}
// As fallback, launch sharer.php in a browser
if (!facebookAppFound) {
String sharerUrl = "https://www.facebook.com/sharer/sharer.php?u=" + urlToShare;
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(sharerUrl));
}
startActivity(intent);
(Regarding the com.facebook.katana package name, see MatheusJardimB's comment.)
The result looks like this on my Nexus 7 (Android 4.4) with Facebook app installed:
The Facebook application does not handle either the EXTRA_SUBJECT or EXTRA_TEXT fields.
Here is bug link: https://developers.facebook.com/bugs/332619626816423
Thanks #billynomates:
The thing is, if you put a URL in the EXTRA_TEXT field, it does
work. It's like they're intentionally stripping out any text.
The usual way
The usual way to create what you're asking for, is to simply do the following:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "The status update text");
startActivity(Intent.createChooser(intent, "Dialog title text"));
This works without any issues for me.
The alternative way (maybe)
The potential problem with doing this, is that you're also allowing the message to be sent via e-mail, SMS, etc. The following code is something I'm using in an application, that allows the user to send me an e-mail using Gmail. I'm guessing you could try to change it to make it work with Facebook only.
I'm not sure how it responds to any errors or exceptions (I'm guessing that would occur if Facebook is not installed), so you might have to test it a bit.
try {
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
String[] recipients = new String[]{"e-mail address"};
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, recipients);
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "E-mail subject");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "E-mail text");
emailIntent.setType("plain/text"); // This is incorrect MIME, but Gmail is one of the only apps that responds to it - this might need to be replaced with text/plain for Facebook
final PackageManager pm = 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);
startActivity(emailIntent);
} catch (Exception e) {
Toast.makeText(this, "Application not found", Toast.LENGTH_SHORT).show();
}
I found out you can only share either Text or Image, not both using Intents. Below code shares only Image if exists, or only Text if Image does not exits. If you want to share both, you need to use Facebook SDK from here.
If you use other solution instead of below code, don't forget to specify package name com.facebook.lite as well, which is package name of Facebook Lite. I haven't test but com.facebook.orca is package name of Facebook Messenger if you want to target that too.
You can add more methods for sharing with WhatsApp, Twitter ...
public class IntentShareHelper {
/**
* <b>Beware,</b> this shares only image if exists, or only text if image does not exits. Can't share both
*/
public static void shareOnFacebook(AppCompatActivity appCompatActivity, String textBody, Uri fileUri) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT,!TextUtils.isEmpty(textBody) ? textBody : "");
if (fileUri != null) {
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setType("image/*");
}
boolean facebookAppFound = false;
List<ResolveInfo> matches = appCompatActivity.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo info : matches) {
if (info.activityInfo.packageName.toLowerCase().startsWith("com.facebook.katana") ||
info.activityInfo.packageName.toLowerCase().startsWith("com.facebook.lite")) {
intent.setPackage(info.activityInfo.packageName);
facebookAppFound = true;
break;
}
}
if (facebookAppFound) {
appCompatActivity.startActivity(intent);
} else {
showWarningDialog(appCompatActivity, appCompatActivity.getString(R.string.error_activity_not_found));
}
}
public static void shareOnWhatsapp(AppCompatActivity appCompatActivity, String textBody, Uri fileUri){...}
private static void showWarningDialog(Context context, String message) {
new AlertDialog.Builder(context)
.setMessage(message)
.setNegativeButton(context.getString(R.string.close), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setCancelable(true)
.create().show();
}
}
For getting Uri from File, use below class:
public class UtilityFile {
public static #Nullable Uri getUriFromFile(Context context, #Nullable File file) {
if (file == null)
return null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
try {
return FileProvider.getUriForFile(context, "com.my.package.fileprovider", file);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} else {
return Uri.fromFile(file);
}
}
// Returns the URI path to the Bitmap displayed in specified ImageView
public static Uri getLocalBitmapUri(Context context, ImageView imageView) {
Drawable drawable = imageView.getDrawable();
Bitmap bmp = null;
if (drawable instanceof BitmapDrawable) {
bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
} else {
return null;
}
// Store image to default external storage directory
Uri bmpUri = null;
try {
// Use methods on Context to access package-specific directories on external storage.
// This way, you don't need to request external read/write permission.
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "share_image_" + System.currentTimeMillis() + ".png");
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
bmpUri = getUriFromFile(context, file);
} catch (IOException e) {
e.printStackTrace();
}
return bmpUri;
}
}
For writing FileProvider, use this link: https://github.com/codepath/android_guides/wiki/Sharing-Content-with-Intents
Here is what I did (for text). In the code, I copy whatever text is needed to clipboard. The first time an individual tries to use the share intent button, I pop up a notification that explains if they wish to share to facebook, they need to click 'Facebook' and then long press to paste (this is to make them aware that Facebook has BROKEN the android intent system). Then the relevant information is in the field. I might also include a link to this post so users can complain too...
private void setClipboardText(String text) { // TODO
int sdk = android.os.Build.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText(text);
} else {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("text label",text);
clipboard.setPrimaryClip(clip);
}
}
Below is a method for dealing w/prior versions
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_share:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, "text here");
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); //TODO
ClipData clip = ClipData.newPlainText("label", "text here");
clipboard.setPrimaryClip(clip);
setShareIntent(shareIntent);
break;
}
return super.onOptionsItemSelected(item);
}
In Lollipop (21), you can use Intent.EXTRA_REPLACEMENT_EXTRAS to override the intent for Facebook specifically (and specify a link only)
https://developer.android.com/reference/android/content/Intent.html#EXTRA_REPLACEMENT_EXTRAS
private void doShareLink(String text, String link) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
Intent chooserIntent = Intent.createChooser(shareIntent, getString(R.string.share_via));
// for 21+, we can use EXTRA_REPLACEMENT_EXTRAS to support the specific case of Facebook
// (only supports a link)
// >=21: facebook=link, other=text+link
// <=20: all=link
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
shareIntent.putExtra(Intent.EXTRA_TEXT, text + " " + link);
Bundle facebookBundle = new Bundle();
facebookBundle.putString(Intent.EXTRA_TEXT, link);
Bundle replacement = new Bundle();
replacement.putBundle("com.facebook.katana", facebookBundle);
chooserIntent.putExtra(Intent.EXTRA_REPLACEMENT_EXTRAS, replacement);
} else {
shareIntent.putExtra(Intent.EXTRA_TEXT, link);
}
chooserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(chooserIntent);
}
Seems in version 4.0.0 of Facebook so many things has changed. This is my code which is working fine. Hope it helps you.
/**
* Facebook does not support sharing content without using their SDK however
* it is possible to share URL
*
* #param content
* #param url
*/
private void shareOnFacebook(String content, String url)
{
try
{
// TODO: This part does not work properly based on my test
Intent fbIntent = new Intent(Intent.ACTION_SEND);
fbIntent.setType("text/plain");
fbIntent.putExtra(Intent.EXTRA_TEXT, content);
fbIntent.putExtra(Intent.EXTRA_STREAM, url);
fbIntent.addCategory(Intent.CATEGORY_LAUNCHER);
fbIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
fbIntent.setComponent(new ComponentName("com.facebook.katana",
"com.facebook.composer.shareintent.ImplicitShareIntentHandler"));
startActivity(fbIntent);
return;
}
catch (Exception e)
{
// User doesn't have Facebook app installed. Try sharing through browser.
}
// If we failed (not native FB app installed), try share through SEND
String sharerUrl = "https://www.facebook.com/sharer/sharer.php?u=" + url;
SupportUtils.doShowUri(this.getActivity(), sharerUrl);
}
This solution works aswell. If there is no Facebook installed, it just runs the normal share-dialog. If there is and you are not logged in, it goes to the login screen. If you are logged in, it will open the share dialog and put in the "Share url" from the Intent Extra.
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, "Share url");
intent.setType("text/plain");
List<ResolveInfo> matches = getMainFragmentActivity().getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo info : matches) {
if (info.activityInfo.packageName.toLowerCase().contains("facebook")) {
intent.setPackage(info.activityInfo.packageName);
}
}
startActivity(intent);
Here is something I did which open Facebook App with Link
shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setComponent(new ComponentName("com.facebook.katana",
"com.facebook.katana.activity.composer.ImplicitShareIntentHandler"));
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, videoUrl);
public void invokeShare(Activity activity, String quote, String credit) {
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, activity.getString(R.string.share_subject));
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Example text");
shareIntent.putExtra("com.facebook.platform.extra.APPLICATION_ID", activity.getString(R.string.app_id));
activity.startActivity(Intent.createChooser(shareIntent, activity.getString(R.string.share_title)));
}
Facebook does not allow to share plain text data with Intent.EXTRA_TEXT but You can share text+link with facebook messanger using this, this works fine for me
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, text+url link);
sendIntent.setType("text/plain");
sendIntent.setPackage("com.facebook.orca");
startActivity(sendIntent);
The easiest way that I could find to pass a message from my app to facebook was programmatically copy to the clipboard and alert the user that they have the option to paste. It saves the user from manually doing it; my app is not pasting but the user might.
...
if (app.equals("facebook")) {
// overcome fb 'putExtra' constraint;
// copy message to clipboard for user to paste into fb.
ClipboardManager cb = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("post", msg);
cb.setPrimaryClip(clip);
// tell the to PASTE POST with option to stop showing this dialogue
showDialog(this, getString(R.string.facebook_post));
}
startActivity(appIntent);
...
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