10

In various Android applications, I use the following code to show an application chooser for email and, after the user has decided for one of the apps, insert a predefined text into the email form:

final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("plain/text");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { "info@example.org" });
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Sample subject");
String contentStr = "";
for (Object o : mArrayList) { // mArrayList: ArrayList<Object>
    content = contentStr+o.toString()+"\n";
}
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, backupStr);
startActivity(Intent.createChooser(emailIntent, "Choose application"));

In the for-loop, the objects' string output is concatenated with the temporary string "contentStr". After every object, there should be a line break ("\n").

So when I test this code on my phone, it works fine and every single object has its own line.

But users report that their email application (Android standard as well) puts everything in one line and ignores the line breaks.

So am I doing anything wrong? Or can I just ignore this bug report as its not an issue which the developer can solve?

caw
  • 30,999
  • 61
  • 181
  • 291
  • 2
    You could try `text/plain` instead of `plain/text`. In addition, you ought to be using `StringBuilder` instead of doing all that concatenation. I am skeptical that either will help with your problem, though. – CommonsWare Mar 14 '12 at 22:45
  • Thank you! But please see my comments below to see a disadvantage of "text/plain". – caw Mar 15 '12 at 23:42
  • 1
    as Marco W. pointed out, "message/rfc822" is the correct mime type for emails – njzk2 Mar 19 '12 at 17:04

5 Answers5

7

You need replace \n to <br/> even you put EXTRA_TEXT. There is my code:

final Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_EMAIL, "xxx@xxx.com");
intent.putExtra(Intent.EXTRA_SUBJECT, "subject");
intent.putExtra(Intent.EXTRA_TEXT, "This\nis\na\ntest!".replace("\n", "<br/>"););
justbilt
  • 458
  • 4
  • 9
7

2 potential leads :

  • Try with \r or \n\r instead of simply \n, or even 2 line breaks.
  • Use HTML formatted line breaks (<br>)

Also, there is something wrong with your code in here

String contentStr = "";
for (Object o : mArrayList) { // mArrayList: ArrayList<Object>
    content = contentStr+o.toString()+"\n";
}
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, backupStr);

This does not put anything in the intent, contentStr is empty, and content only contains the last object.

This is a better, shorter and more efficient method:

contentStr = TextUtils.join("\n", mArrayList);
njzk2
  • 38,969
  • 7
  • 69
  • 107
  • 3
    Thank you very much for the alternative with `TextUtils.join()`. I used '\n' because this is for Linux (and others) and `\r\n` is for Windows (and others), isn't it? Wikipedia suggests to use `System.getProperty("line.separator")` for line breaks in Java. Is this a good solution? – caw Mar 19 '12 at 22:07
  • i think it is. that would be supposed to give you the line separator used by the system you are on. However, android is linux-based, so it should always be `\n`. Have you been able to reproduce the issue? – njzk2 Mar 20 '12 at 09:22
0

After a few hours testing various methods and scenarios, this is my answer that stays valid in the year 2020. I tested it with Gmail, Outlook, and Samsung's Mail apps:

public static void composeEmail(@NonNull Activity activity,
                                    @NonNull String address,
                                    @Nullable String subject,
                                    @Nullable String body) {
        Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
        emailIntent.setData(Uri.parse("mailto:"));
        emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {address});
        emailIntent.putExtra(Intent.EXTRA_TEXT, body);
        emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
        activity.startActivity(Intent.createChooser(emailIntent, activity.getString(R.string.choose_email_client)));
    }

You use \n as line breaks in the body text and it simply works. Please be aware that if you mix \n with HTML tags (<br/>), Outlook will assume the email body is html-formatted and will ignore non-html line breaks (\n)!

My method shows only email clients on the app chooser list, just as it should.

Plus you can use "prettified" email addresses, like John Doe <john.doe@example.com>.

javaxian
  • 1,815
  • 1
  • 21
  • 26
0

use:

emailIntent.setType("text/plain");

ACTION_SEND

final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("text/plain");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { "info@example.org" });
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Sample subject");
String contentStr = "";
for (Object o : mArrayList) { // mArrayList: ArrayList<Object>
    content = contentStr+o.toString()+"\n";
}
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, backupStr);
startActivity(Intent.createChooser(emailIntent, "Choose application"));
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • Thank you! When I use "text/plain", the application chooser shows all apps that can handle text messages (e.g. SMS, Facebook). But when I use my old "plain/text", only the email applications show up. Why is this so? I want only the email applications. – caw Mar 15 '12 at 23:41
  • 2
    @MarcoW.: `plain/text` does not only give you email applications. It will give you anything the user has installed that handle invalid MIME types. If you want to limit things to email, use `ACTION_SENDTO` and a `mailto:` `Uri`. – CommonsWare Mar 15 '12 at 23:48
  • 1
    Thanks! "ACTION_SENDTO" doesn't work for me. But I found that using "message/rfc822" as the MIME type helps. Is this the right one for sending emails? – caw Mar 16 '12 at 17:30
  • Nevertheless, the real problem of this question is not yet solved. – caw Mar 18 '12 at 14:23
-1

I use something like the following to be sure to not get SMS/Twitter/Facebook apps in there:

Intent emailIntent = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:someemail@gmail.com"));
                emailIntent.setType("text/plain");
                emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"someemail@gmail.com"});
                emailIntent.putExtra(Intent.EXTRA_TEXT, msg );
                emailIntent.putExtra(Intent.EXTRA_SUBJECT, "This is my Error Report");

And here the String msg was made using a StringBuilder and contains \n for line breaks. Basically, I think you just have to change your MIME type and you'll be set.

Sleepybear
  • 362
  • 1
  • 9
  • Thank you very much! StringBuilder is a good hint. Please see my comment to Jorgesys' answer. Even your additional Uri.parse() doesn't work :( – caw Mar 15 '12 at 23:41
  • This solution still shows a lot of non-email apps on the chooser list. – javaxian Aug 06 '20 at 11:13