Jump to content
Tim Clover

Send Email from Android with HTML message body

Recommended Posts

I'm having difficulties getting HTML into the body of an email message when I send using intents, which opens the email app on the device to send the message. My application is able to put the html code into the body via this method but the message just shows the html code, not the browser type view of the code. What am I doing wrong?

Code follows:

procedure TfrmMain.SendMailViaIntent(const AText: string);
var
  Intent: JIntent;
  sMessageBody:string;
  Recipients: TJavaObjectArray<JString>;
begin
  sMessageBody:=Body.Lines.Text;
  //Intent := TJIntent.Create;
  Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_SEND);
  Recipients := TJavaObjectArray<JString>.Create(1);
  Recipients.Items[0] := StringToJString(AText);
  //Intent.setType(StringToJString('message/rfc822'));
  Intent.setType(StringToJString('text/html'));//not showing as html
  Intent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL,Recipients);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(edOutSubject.Text));
  //Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, StringToJString(sMessageBody));
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(sMessageBody));
  Intent.putExtra(TJIntent.JavaClass.EXTRA_HTML_TEXT, StringToJString(sMessageBody));
  TAndroidHelper.Activity.startActivity(TJIntent.JavaClass.createChooser(Intent,
                                        StrToJCharSequence('Which email app?')));
end;
 

Share this post


Link to post
On 4/14/2023 at 10:27 AM, Tim Clover said:

  Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(sMessageBody));
  Intent.putExtra(TJIntent.JavaClass.EXTRA_HTML_TEXT, StringToJString(sMessageBody));

If you include EXTRA_HTML_TEXT, that is supposed to be an alternative format to the plain text in EXTRA_TEXT.  So maybe don't put HTML code in EXTRA_TEXT if you also put it in EXTRA_HTML_TEXT?

 

Note that not all (or very few?) email apps actually support EXTRA_HTML_TEXT, which is why EXTRA_TEXT is also required.  So it could be that on your device, EXTRA_HTML_TEXT is being ignored and displaying EXTRA_TEXT as plain text instead, which might explain why you are seeing the HTML code as plain text instead of as formatted text.

 

Also, when adding HTML code to EXTRA_TEXT or EXTRA_HTML_TEXT, try passing it through the Html.FromHtml() method first, rather than adding it as a plain string.

  • Like 1

Share this post


Link to post

I will try adding text just to EXTRA_HTML_TEXT as  you suggest. I'm not  sure how to access Html.FromHtml(), I am using the following units:

{$IFDEF ANDROID}
  Androidapi.Helpers, Androidapi.JNIBridge,
  Androidapi.JNI.JavaTypes, Androidapi.JNI.GraphicsContentViewText, FMX.Platform.Android,
  Androidapi.JNI.Os, Androidapi.JNI.Net, Androidapi.JNI.Webkit,
{$ENDIF}

Is the Html.FromHtml() function part of these units?
Could you possibly give me an example of how to call the function?

 

Thank you very much for your response to my question!

 

Tim Clover

Share this post


Link to post
1 hour ago, Tim Clover said:

I will try adding text just to EXTRA_HTML_TEXT as  you suggest.

That is not what I suggested.  I suggested putting plain text (no HTML code) in EXTRA_TEXT, and HTML code in EXTRA_HTML_TEXT.

1 hour ago, Tim Clover said:

I'm not  sure how to access Html.FromHtml(), I am using the following units:

...

Is the Html.FromHtml() function part of these units?

I doubt it. You will likely have to import it manually.

Importing an Android Class For Use in Delphi

Convert any Android API to Delphi and C++ Builder units to utilize in your FireMonkey Android Projects

1 hour ago, Tim Clover said:

Could you possibly give me an example of how to call the function?

Once you have it imported properly, I think it would just be as simple as:

Intent.putExtra(TJIntent.JavaClass.EXTRA_HTML_TEXT,
  TJHtml.JavaClass.fromHtml(StringToJString(sMessageBody), 0)
);

 

Share this post


Link to post

Thank you all so much for your help! I never would have been able to wade through this aspect of Delphi without your help. I am a self taught Delphi software developer age 70. I created my job and my company in 1993,

 

Tim Clover

Cloversoft

Share this post


Link to post

Thank you so much for your help Remy and Dave. I gave it the old college try but after ultimately striking out I found this:

From StackOverflow 2018: "Google has removed that feature from gmail application so its not possible to send tag content to gmail . "

I have tried every permutation with Intents method including all of the suggestions that Remy Lebeau and Dave Nottage so kindly sent me, The email app on the device (GMail) always shows the unformatted text instead of the HTML text. The funny thing is I have a working version that uses Indy that can send an email message body in HTML and will show it (in gmail) formatted properly. The whole reason I went down this rabbit hole was to make setting up the email easier for the user. If you use smtp.gmail.com to send it, you need to jump through a bunch of hoops to do it. ie: set up 2 factor ID, get an app password. Users will just forget about using your app is it is too complicated to set up.

 

Final try works but no HTML shown

procedure TfrmMain.SendMailViaIntent(const AText: string);
var
  Intent: JIntent;
  sMessageBody,sMessagePlaintext:string;
  Recipients: TJavaObjectArray<JString>;
begin
  sMessageBody:=Body.Lines.Text;
  sMessagePlaintext:=slMessage.Text;
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
  Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
  Recipients := TJavaObjectArray<JString>.Create(1);
  Recipients.Items[0] := StringToJString(AText);
  Intent.setType(StringToJString('text/html'));//not showing as html
  Intent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL,Recipients);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(edOutSubject.Text));
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT,StringToJString(sMessagePlaintext));
  Intent.putExtra(TJIntent.JavaClass.EXTRA_HTML_TEXT, TJHtml.JavaClass.fromHtml(StringToJString(sMessageBody), 0));
  SharedActivity.startActivity(TJIntent.JavaClass.createChooser(Intent,
                                        StrToJCharSequence('Which email app?')));

end;
Tim Clover,

Cloversoft

Share this post


Link to post
21 hours ago, Tim Clover said:

From StackOverflow 2018: "Google has removed that feature from gmail application so its not possible to send tag content to gmail . "

Yeah, that is about what I found, too.  Apparently, there aren't that many apps that actually support EXTRA_HTML_TEXT nowadays.

21 hours ago, Tim Clover said:

The whole reason I went down this rabbit hole was to make setting up the email easier for the user. If you use smtp.gmail.com to send it, you need to jump through a bunch of hoops to do it. ie: set up 2 factor ID, get an app password.

You need an app password only if you don't use OAuth2 authentication, which is what Google wants you to use nowadays (well, they WANT you to use their own APIs, but if you have to use SMTP directly, use OAuth2).

 

Indy's GitHub repo currently has a sasl-oauth branch which adds a few TIdSASL components for OAuth2, including Gmail's XOUATH2.  You would still be responsible for implementing your own code to retrieve an OAuth2 token from Gmail (Indy doesn't have components for that purpose), but at least you could then have Indy use that token during SMTP authentication, no app password needed.

Share this post


Link to post

Hi, 

 

I'm trying to send a email like that with a Attachment via Intent but the attachment is not attached.

 

I created the fileprovider

 

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
 name="external_files" path="." />
</paths>

 

and updated my manifest 

 <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="%package%.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/fileprovider"/>
    </provider>

 

 

<code>

  JRecipient := TJavaObjectArray<JString>.Create(1);
  JRecipient.Items[0] := StringToJString(Recipient);

  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
  Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL, JRecipient);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(Subject));
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(Content));

  if Attachment <> '' then
  begin
    if TJBuild_VERSION.JavaClass.SDK_INT >= TJBuild_VERSION_CODES.JavaClass.N then
    begin
      lFile := TJFile.JavaClass.init(StringToJString(Attachment));
      Intent.setFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
      Data := TJcontent_FileProvider.JavaClass.getUriForFile(TAndroidHelper.Context,
      StringToJString(JStringToString(TAndroidHelper.Context.getApplicationContext.getPackageName)+'.provider'), lFile);
    end
    else
      Data := TJnet_Uri.JavaClass.parse(StringToJString('file://' + Attachment));

 

    Intent.setDataAndType(Data, StringToJString('message/rfc822'));

    SharedActivity.startActivity(Intent);

end;

</code> 

 

Thank you.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×