What is the purpose of using Intent.createChooser() in StartActivity() while sending email in Android
Asked Answered
T

8

43

When ever we need to send an email in Android we will invoke registered email application using Intent.ACTION_SEND like below

Intent i = new Intent(Intent.ACTION_SEND);
startActivity(Intent.createChooser(i, "Send mail..."));

My doubt is why do we need to use Intent.createChooser in startActivity rather than using startActivty(i). Is there any specific reason of using Intent.createChooser()?

Temptress answered 27/9, 2010 at 13:29 Comment(0)
C
50

AFAIK, if you use Intent.createChooser, there are three differences:

  1. You can specify the title of the chooser dialog to make it more clear.

  2. The system will always present the chooser dialog even if the user has chosen a default one.

  3. If your intent created by Intent.createChooser doesn't match any activity, the system will still present a dialog with the specified title and an error message No application can perform this action. Or for the normal intent, you may get an Android runtime error with: Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent

Candelabra answered 2/9, 2014 at 4:16 Comment(4)
This is regarding 3rd point. ActivityNotFoundException will get only when you use normal intent instead of Intent.createChooser. This is also another advantage of using Intent.createChooser. You can change 3rd point according to this.Sandi
@Candelabra do you know how to clear the user selected default one?Glyconeogenesis
@PhaniRithvij try PackageManger.clearPackagePreferredActivities, but this method can only clear app's own preferred settings.Candelabra
I asked a question here stackoverflow.com/q/59279969/8608146 on how to clear the user-selected option.Glyconeogenesis
P
12

The chooser enables the user to pick another mail application than the default. Its very useful if you use normal gmail (privat) and email (work related) and you want to choose which one to take.

Should always be used...

Prichard answered 27/9, 2010 at 13:37 Comment(4)
But along with mailApplication, messaging application is also poping up if I have only one mail application in my device.Then how to restrict to only one application i.e. only mail application to be launched in response to the intentTemptress
@Android_programmer_camera: Please allow the user to send whatever it is by whatever means they wish. Why do you feel that you need to limit the user's options?Flea
Hey,I did n't get u.Can u explain it?Temptress
CommonsWare just said, you shouldn't filter the options, you should let the user decide what he want to start. I strongly recommend this way!Prichard
E
11

Way old message but for others who come across it, you can set the type on the Intent to the mime type of emails, which will at least limit it to applications that can send that appropriate type of message:

Intent i = new Intent(Intent.ACTION_SEND); 
i.setType( "message/rfc822");
startActivity(Intent.createChooser(i, "Send mail..."));

Makes the chooser dialog much cleaner.

Epilepsy answered 14/7, 2012 at 4:59 Comment(0)
P
6

If you don't use createChooser(), the system will still present the chooser dialog unless the user has already expressed their decision as to which installed program to use for the given task (or they have withdrawn their previous decision).

If you do use createChooser(), the system will always present the dialog, even if there already is an expressed preference.

So, both are absolutely correct, you have to decide which one to use in any given case. Your mileage might vary, but basically, if you offer up a format like a text, an image, a video or similar for display or editing, you probably want to omit createChooser() so that whatever the user already prefers can start immediately. On the other hand, if you want to share something that you expect the user to handle with a different installed program (say, send an e-mail, Facebook, chat, whatever) every time, you probably want to use createChooser() to make it easy for your user to select on the fly.

Phyllis answered 26/3, 2014 at 21:4 Comment(0)
C
1

I personally use:

try {
    startActivity(i);
} catch (ActivityNotFoundException e) {
    startActivity(Intent.createChooser(i, null));
}

So it will use default if user has default, will popup "no app" window if no app. Both are happy.

Core answered 4/4, 2017 at 18:23 Comment(1)
So you're basically calling startActivity twice and using chooser to only display an error. Don't think its wiseIsisiskenderun
C
1

From the document

Android provides two ways for users to share data between apps:

  • The Android Sharesheet is primarily designed for sending content outside your app and/or directly to another user. For example, sharing a URL with a friend.
  • The Android intent resolver is best suited for passing data to the next stage of a well-defined task. For example, opening a PDF from your app and letting users pick their preferred viewer.
val sendIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, "Text to send.")
    type = "text/plain"
}


// WILL start Android intent resolver
startActivity(sendIntent)


// WILL start Android ShareSheet
val shareIntent = Intent.createChooser(sendIntent, null)
startActivity(shareIntent)

Android Sharesheet have some benefits such as it supports DirectShare, rich preview with Copy option from Android 10 (but some few devices don't have rich preview even Android > 10)

Completion answered 28/6, 2022 at 13:37 Comment(0)
K
0

I recommend having a look at the de.cketti.mailto:email-intent-builder library instead of using the API provided by the Android framework. This article explains what is broken and why you should switch.

Khorma answered 17/12, 2021 at 8:17 Comment(0)
M
0

// can call method like this, in case of image please pass bitmap too as paramter

fun onShareClick(url: String?, title: String?) {
        requireContext().startActivity(
            requireContext().createShareIntent(
                url = url ?: "",
                title = title
            )
        )
    }

// if you want to share text + url

fun Context.createShareIntent(url: String, title: String? = null): Intent {

return ShareCompat.IntentBuilder(this).apply {
         type = "text/plain"
    val extraText = title?.let {
        "$title\n\n$url"
    } ?: url
    setText(extraText)

}.intent

// if you want to share image + text

fun Context.createShareIntent(url: String, title: String? = null, bitmap: Bitmap?): Intent {

return ShareCompat.IntentBuilder(this).apply {
        setType("image/*")
    
    val extraText = title?.let {
        "$title\n\n$url"
    } ?: url

    // if you want to add image bitmap
    bitmap?.let {
        val uri = saveImageInQ(bitmap) // this is custom method to convert bitmap into image uri
        setStream(uri)
    }
    setText(extraText)

}.intent
Maryellen answered 26/2, 2024 at 6:22 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.