I am having an issue with Email Intent in Android.
The recipients field is not populating properly.
My code is as such:
Extensions.kt
// Returns a Mail Intent
fun requireMailIntent(subject: String, body: String) = Intent(Intent.ACTION_SENDTO).apply {
data = Uri.parse("mailto:")
putExtra(Intent.EXTRA_EMAIL, arrayOf("email#gmail.com"))
putExtra(Intent.EXTRA_SUBJECT, subject)
putExtra(Intent.EXTRA_TEXT,body)
}
/**
* Checks whether the intent has an app that can
* handle it.
* Should be called before starting an intent
**/
fun Intent.hasSuccessor(context: Context) = resolveActivity(context.packageManager) != null
Fragment.kt
// Submit button
binding.ButtonSubmit.setOnClickListener {
val emailConstruct = constructEmail()
val intent = requireMailIntent(emailConstruct.first, emailConstruct.second)
if(intent.hasSuccessor(requireContext())){
Log.v("INTENT_TEST", "Launching Intent")
startActivity(intent)
}else{
Log.v("INTENT_TEST", "No app found")
}
}
private fun constructEmail(): Pair<String,String>{
val subject = "MES :: Bug Report :: ${viewModel.bugIdentified}"
val message = "Below are the steps \n ${viewModel.bugSteps}"
return Pair(subject, message)
}
Manifest.xml
<!-- For basic package querying, ie browsers, email... -->
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
Gradle
// SDK Versions
sdk_compiled_version = 30
sdk_minimum_version = 24
// Build tools
build_tools = "29.0.3"
Upon clicking the button, Android shows me the app chooser, but when i click Gmail, everything populates except the recipients field.
Can someone please help ?
Try using URI
val uriText = "mailto:contact#example.com" +
"?subject=" + "your subject here" +
"&body=" + body
val uri = Uri.parse(uriText)
val sendIntent = Intent(Intent.ACTION_SENDTO)
sendIntent.data = uri
startActivity(Intent.createChooser(sendIntent, "Send Email").addFlags(FLAG_ACTIVITY_NEW_TASK))
Related
This is my hyperlink
String linkText = "Visit the <a href='http://stackoverflow.com'>StackOverflow</a> web page."
I have add this in below function
fun whatsappshr(context: Context, displayData: Display_data) {
val message : String = displayData.appdata + linkText
val Intentfun = Intent(Intent.ACTION_SEND)
Intentfun.type = "text/plain"
Intentfun.setPackage("com.whatsapp")
Intentfun.putExtra(Intent.EXTRA_TEXT, message)
try {
ContextCompat.startActivity(itemView.context, Intentfun, null)
} catch (ex: ActivityNotFoundException) {
Toast.makeText(itemView.context, "Whatsapp not Installed", Toast.LENGTH_SHORT).show()
}
}
when my app share the data via Intent, it does not send a link. It send the whole data from linkText.
Is there any way to send hyperlink via android intent? Guys, please help me to resolve this.
The code below used to work a week ago. It's purpose is to allow the user to choose if he want to send a text message using WhatsApp or SMS, but now when I choose WhatsApp it doesn't do anything, although SMS keeps working.
Looking at the logcat it's printing: 2018-10-25 18:28:28.915 2147-6714/? I/ActivityManager: START u0 {act=android.intent.action.SENDTO dat=smsto:xxxxxxxxxxx flg=0x3000000 cmp=com.whatsapp/.Conversation (has extras)} from uid 10096 Even passing a valid number with country code, it is printing smsto:xxxxxxxxxxx.
Is there any working code for this purpose or know about this problem?
fun sendMessageToNumber(number: String, text: String) {
val cleanNumber = number.cleanText()
val uri = Uri.parse("smsto:$cleanNumber")
val sendIntent = Intent(Intent.ACTION_SENDTO, uri)
sendIntent.putExtra("sms_body", text)
context?.startActivity(Intent.createChooser(sendIntent, context.getString(R.string.fragment_account_chooser_message_title)))
}
In one of my project I have used following code for sending whatsapp message :
fun sendWhatsappMsg(){
var toNumber = "+91 xxxxx xxxxx" // contains spaces.
toNumber = toNumber.replace("+", "").replace(" ", "")
val sendIntent = Intent("android.intent.action.MAIN")
sendIntent.putExtra("jid", "$toNumber#s.whatsapp.net")
sendIntent.putExtra(Intent.EXTRA_TEXT, "Hello")
sendIntent.action = Intent.ACTION_SEND
sendIntent.setPackage("com.whatsapp")
sendIntent.type = "text/plain"
startActivity(sendIntent)
}
And to send text message I have used following code :
fun sendTextMsg(){
val phone = "xxxxxxxxxx"
val msg = "smsto:" + phone
val smsUri = Uri.parse(msg)
val smsIntent = Intent(Intent.ACTION_SENDTO, smsUri)
startActivity(smsIntent)
}
You can try this. Both are working for me.
I am trying to share file with email clients and Google Drive. Now, in following code, only Google drive is opening and email clients are not opening at all. I can provide equivalent Java code of following code if required
val photoURI: Uri = FileProvider.getUriForFile(this, "com.emerson.oversight.com.emerson.oversight.provider",
File(this.cacheDir.path + "/SensorReport.pdf"))
val emailIntent = Intent(Intent.ACTION_SENDTO)
emailIntent.data = Uri.parse("mailto:")
emailIntent.putExtra(Intent.EXTRA_STREAM, photoURI)
emailIntent.putExtra(Intent.EXTRA_EMAIL, "asd#dsa.dsa")
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "dsadsada")
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
val driveIntent = Intent()
driveIntent.`package`= "com.google.android.apps.docs"
driveIntent.action = Intent.ACTION_VIEW
val fileID = File(this.cacheDir.path + "/SensorReport.pdf")
val url = "https://docs.google.com/file/d/" + fileID
driveIntent.data = Uri.parse(url)
val openInChooser = Intent.createChooser(driveIntent, getString(R.string.share_using))
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayListOf(emailIntent))
startActivity(openInChooser)
Please help
You were almost there, the only missing piece in the puzzle is the getPackageManager().queryIntentActivities method that will return all activities that can handle your email intent. With the ResolveInfo returned you can build an intent for each email option to be displayed in the chooser. Then you can pass the array of those intents as Intent.EXTRA_INITIAL_INTENTS. You could even exclude certain packages if you like here. So the final part of your code would look something like this:
val openInChooser = Intent.createChooser(driveIntent, getString(R.string.share_using))
val emailOptionIntents = mutableListOf<Intent>()
val resInfo = getPackageManager().queryIntentActivities(emailIntent, 0)
if (!resInfo.isEmpty()) {
for (resolveInfo in resInfo) {
val emailOptionIntent = Intent(Intent.ACTION_SENDTO)
emailOptionIntent.data = Uri.parse("mailto:")
emailOptionIntent.putExtra(Intent.EXTRA_STREAM, photoURI)
emailOptionIntent.putExtra(Intent.EXTRA_EMAIL, "asd#dsa.dsa")
emailOptionIntent.putExtra(Intent.EXTRA_SUBJECT, "dsadsada")
emailOptionIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
emailOptionIntent.`package` = resolveInfo.activityInfo.packageName
emailOptionIntents.add(emailOptionIntent)
}
}
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, emailOptionIntents.toTypedArray())
startActivity(openInChooser)
I got a crash when I try to send an email using intent with kotlin
here's my function
/**
* intentEmail is called when we need to send email
*
* #param price int
*/
fun intentEmail(price: Int) {
var intent = Intent(Intent.ACTION_SEND)
//intent.putExtra(Intent.EXTRA_EMAIL, addressees)
intent.data= Uri.parse("mailto:")
intent.putExtra(Intent.EXTRA_SUBJECT, "Just Java order for $name")
intent.putExtra(Intent.EXTRA_TEXT, createOrderSummary(price))
if(intent.resolveActivity(packageManager) != null){
startActivity(intent)
}
}
and the crash happens when calling startActivity(intent)
and here's my LogCat
maybe your phone is not accept this intent action. you should use try catch the avoid this crash.
you can also use the phone's other "send mail" app, so that you can find out what's the correct intent.
The issue was in
var intent = Intent(Intent.ACTION_SEND)
when I changed it to
var intent = Intent(Intent.ACTION_SENDTO)
it works fine thanks to #lampenlampen
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.