Open mail app via intent doesn't open chooser - android

I'm trying to open an mail application on Android via intent. The purpose is to have a button in the app that will open your mail inbox. However when I use:
val intent = Intent(Intent.ACTION_MAIN)
intent.addCategory(Intent.CATEGORY_APP_EMAIL)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(Intent.createChooser(intent, "Email"))
It always opens gmail, while I also have Outlook installed. The only way I get to choose between the mail apps is when yo use the mailto. But I don't intent to send an email, so it is not desired to use that intent.
Doesn't Outlook support this Intent?

use the following snippet to open to outlook directly from a different app
context.startActivity(
Intent().apply {
action = Intent.ACTION_MAIN
addCategory(Intent.CATEGORY_LAUNCHER)
component = ComponentName(
outlookLaunchIntent?.component?.packageName,
outlookLaunchIntent?.component?.className
)
setPackage(outlookLaunchIntent.package)
}
)
com.microsoft.office.outlook is the package name for outlook
For sending it to all email clients use a uri like this
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.parse("mailto:?subject=" + subject + "&body=" + body);
intent.setData(data);
startActivity(intent);
Ref:How to open Email program via Intents (but only an Email program)

Related

Android send user to email client chooser

I am trying to redirect user to check his email via available email clients. Currently what I have achieved is to send the user directly to Gmail client. Below there are some functions that I use to generate implicit intent:
fun attept1(): Intent {
val intent = Intent.makeMainSelectorActivity(
Intent.ACTION_MAIN,
Intent.CATEGORY_APP_EMAIL
)
intent.addFlags(FLAG_ACTIVITY_NEW_TASK)
return intent
}
fun attempt2(): Intent {
val intent = Intent(ACTION_VIEW)
intent.type = "message/rfc822"
intent.addFlags(FLAG_ACTIVITY_NEW_TASK)
return intent
}
//... somewhere in the code
val emailIntent = attempt1() //or attempt2()
startActivity(emailIntent)
With attempt 1 I am successfully redirecting the user to Gmail but I do have at least 5 email clients installed (BlueMail, Outlook, Yahoo Mail, Email, Temp Mail). They're ignored completely.
With attempt 2, at first it was showing unrelated apps like Slack, but after I have installed other email clients it just shows a toast message: Can't open this file. I have tried with Intent.createChooser(intent, "Choose client: ") but it didn't work either.

Opening a WhatsApp chat with a specific contact by clicking on a button in my app (Kotlin)

How can I Open a Whatsapp chat with a specific contact by clicking on a button in my app?
That's the code I use. It opens WhatsApp and let me search the contact I want to send the message to, but it doesn't open the WhatsApp chat with the specific contact number I gave it to.
whatsappButton.setOnClickListener{
var con = itemView.context
val textToShare = "*כח אדם*"
val phoneNumber = blogPost.phone
val sendIntent = Intent()
sendIntent.action = Intent.ACTION_SEND
sendIntent.type = "text/plain"
sendIntent.putExtra("jid", phoneNumber+"#s.whatsapp.net")
sendIntent.putExtra(Intent.EXTRA_TEXT, textToShare)
val extra = sendIntent.extras
startActivity(con,sendIntent,extra)
}
If you want send a message to a specific contact from Contacts app, you should first require permission to access contacts, get the number and try with this:
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");
startActivity(sendIntent);
Ref: https://stackoverflow.com/a/40285262/2895571
Please check this answer here
Use the following bit of code:
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);
First option: using Uri to convert whatsapp web url into button:
open_whatsapp.setOnClickListener {
val url = "https://api.whatsapp.com/send?phone=XXXXXXXXXX"
val openWhatsappIntent = Intent(Intent.ACTION_VIEW)
openWhatsappInten.data = Uri.parse(url)
startActivity(openWhatsappInten)
}
Second option; this is used as a href in web development :
Tel: XXX XXXX XX
maybe you can add Html format into TextView (Html.fromHtml()) and enable links clickeable to open the whatsapp application.
if you want send message to particular contact in whatsapp , use below url and particular mobile no to the Intent(including Country code).
String url = "https://wa.me/";
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url+mobile_no));
startActivity(browserIntent);

Choose among SMS, WhatsApp, or Telegram to send message

At a contact list in my Android app, there is an option to launch WhatsApp implemented as follows:
// Country code is required
final String phoneNumber = "+15555555555";
final String packageName = "com.whatsapp";
Intent intent = getPackageManager().getLaunchIntentForPackage(packageName);
if (null == intent) {
// Launch Google Play at WhatsApp homepage
intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=" + MESSAGE_PACKAGE_NAME));
startActivity(intent);
return;
}
intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:" + phoneNumber));
intent.setPackage(packageName);
startActivity(intent);
but this only allow me to send messages through WhatsApp.
Removing the package name and setting the intent type to
intent.setType("vnd.android-dir/mms-sms");
launched the SMS application.
How can we choose among all apps installed at an Android device that use the phone number as and identifier (Hangouts, SMS, Skype, Line, Telegram, Viber, WhatsApp, etc)?
Fortunately Android Intent.createChooser is smart enough to figure out the apps that understand the phone numbers as an identifier :-)
// Country code is required
String phoneNumber = "+15555555555";
Uri uri = Uri.parse("smsto:" + phoneNumber);
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(Intent.createChooser(intent, "Send message"));

send a photo through MMS message

I am trying to send a photo through MMS message, I am using the following known snippet
Intent i = new Intent(Intent.ACTION_SEND);
i.putExtra(Intent.EXTRA_TEXT, "This is an MMS message");
String sendfilepath = "file://" + sendfile.toString() + ".jpg";
i.putExtra(Intent.EXTRA_STREAM,Uri.parse(sendfilepath)) ;
i.setType("image/jpeg");
It works with my Sony device. The pop up menu shows the messaging app along with other apps.
But with HTC it does not show the Messaging app. It shows Bluetooth, Facebook, Mail, etc. How can I make it show the Messaging app in the "Complete action using" list
You can use this technique to check for HTC sense device and react appropriately to send the proper "version" of the intent.
Uri uri = Uri.fromFile(imgFile);
//HTC Sense intent
Intent sendIntent = new Intent("android.intent.action.SEND_MSG");
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
sendIntent.setType("image/"+type);
List<ResolveInfo> resolves = getPackageManager().queryIntentActivities(sendIntent,PackageManager.MATCH_DEFAULT_ONLY);
if (resolves.size() > 0) {
// This branch is followed only for HTC
startActivity(sendIntent);
} else {
// Else launch the non-HTC sense Intent
sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
sendIntent.setType("image/"+type);
startActivity(Intent.createChooser(sendIntent,"Send"));
}

Android Intent Chooser to only show E-mail option

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

Categories

Resources