Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article describes how you can use the .NET Multi-platform App UI (.NET MAUI) IEmail interface to open the default email app. When the email app is loaded, it can be set to create a new email with the specified recipients, subject, and body.
The default implementation of the IEmail
interface is available through the Email.Default property. Both the IEmail
interface and Email
class are contained in the Microsoft.Maui.ApplicationModel.Communication
namespace.
Get started
To access the email functionality, the following platform specific setup is required.
If your project's Target Android version is set to Android 11 (R API 30) or higher, you must update your Android Manifest with queries that use Android's package visibility requirements.
In the Platforms/Android/AndroidManifest.xml file, add the following queries/intent
nodes in the manifest
node:
<queries>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
</intent>
</queries>
Using Email
The Email functionality works by providing the email information as an argument to the ComposeAsync method. In this example, the EmailMessage type is used to represent the email information:
if (Email.Default.IsComposeSupported)
{
string subject = "Hello friends!";
string body = "It was great to see you last weekend.";
string[] recipients = new[] { "john@contoso.com", "jane@contoso.com" };
var message = new EmailMessage
{
Subject = subject,
Body = body,
BodyFormat = EmailBodyFormat.PlainText,
To = new List<string>(recipients)
};
await Email.Default.ComposeAsync(message);
}
File attachments
When creating the email provided to the email client, you can add file attachments. The file type (MIME) is automatically detected, so you don't need to specify it. Some mail clients may restrict the types of files you send, or possibly prevent attachments altogether.
Use the EmailMessage.Attachments collection to manage the files attached to an email.
The following example demonstrates adding an image file to the email attachments.
if (Email.Default.IsComposeSupported)
{
string subject = "Hello friends!";
string body = "It was great to see you last weekend. I've attached a photo of our adventures together.";
string[] recipients = new[] { "john@contoso.com", "jane@contoso.com" };
var message = new EmailMessage
{
Subject = subject,
Body = body,
BodyFormat = EmailBodyFormat.PlainText,
To = new List<string>(recipients)
};
string picturePath = Path.Combine(FileSystem.CacheDirectory, "memories.jpg");
message.Attachments.Add(new EmailAttachment(picturePath));
await Email.Default.ComposeAsync(message);
}
Control file locations
Important
This section only applies to Android.
In some scenarios on Android, such as when a file is in private storage, it can be copied into the app cache which is then shared via an Android FileProvider
. However, this can unintentionally expose the entire cache and app data to an attacker. This can be prevented by adding a file provider file paths override file to your app, and ensuring that files are copied to the location specified in this file prior to sharing.
To add a file provider file paths override file to your app, add a file named microsoft_maui_essentials_fileprovider_file_paths.xml to the Platforms\Android\Resources\xml folder in your app. Therefore, the full relative file name to the project should be Platforms\Android\Resources\xml\microsoft_maui_essentials_fileprovider_file_paths.xml. Then, add XML to the file for your required paths:
<?xml version="1.0" encoding="UTF-8" ?>
<paths>
<external-path name="external_files" path="sharing-root" />
<cache-path name="internal_cache" path="sharing-root" />
<external-cache-path name="external_cache" path="sharing-root" />
</paths>
For more information about file provider paths, see FileProvider on developer.android.com.
Prior to sharing a file, you should ensure it's first written to the sharing-root folder in one of the locations from the override file:
// Write into the specific sub-directory
var dir = Path.Combine(FileSystem.CacheDirectory, "sharing-root");
Directory.CreateDirectory(dir);
var file = Path.Combine(dir, "mydata.txt");
await File.WriteAllTextAsync(file, $"My data: {count}");
// Share the file
await Launcher.OpenAsync(new OpenFileRequest
{
Title = "My data",
File = new ReadOnlyFile(file),
});
You can verify that the file is being shared correctly if the shared URI excludes the sharing root directory. For example, if you share the file <CacheDirectory>/sharing-root/mydata.txt and the shared URI is content://com.companyname.overwritefileproviderpaths.fileProvider/internal_cache/sharing-root/mydata.txt
then the file provider isn't using the correct path. If the shared URI is content://com.companyname.overwritefileproviderpaths.fileProvider/internal_cache/mydata.txt
then the file provider is using the correct path.
Warning
When sharing a file, if you receive an Java.Lang.IllegalArgumentException
, with a message similar to "Failed to find configured root that contains /data/data/com.companyname.overwritefileproviderpaths/cache/some-non-sharing-path/mydata.txt", you are most likely sharing a file that's outside of the sharing-root.
Platform Differences
Not all email clients for Android support EmailBodyFormat.Html, since there is no way to detect this, we recommend using EmailBodyFormat.PlainText when sending emails.