本文介绍如何使用 .NET 多平台应用 UI (.NET MAUI) IEmail 接口打开默认电子邮件应用。 加载电子邮件应用后,可以将其设置为使用指定的收件人、主题和正文创建新电子邮件。
IEmail
接口的默认实现可通过 Email.Default 属性获得。
IEmail
接口和 Email
类都包含在 Microsoft.Maui.ApplicationModel.Communication
命名空间中。
入门
若要访问电子邮件功能,需要以下特定于平台的设置。
如果项目的目标 Android 版本设置为 Android 11(R API 30) 或更高版本,则必须使用 Android 包可见性要求的查询更新 Android 清单文件。
在 Platforms/Android/AndroidManifest.xml 文件中,在 manifest
节点中添加以下 queries/intent
节点:
<queries>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
</intent>
</queries>
使用电子邮件
电子邮件功能的工作原理是向 ComposeAsync 方法提供电子邮件信息作为参数。 在此示例中,EmailMessage 类型用于表示电子邮件信息:
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);
}
文件附件
创建提供给电子邮件客户端的电子邮件时,可以添加文件附件。 会自动检测文件类型(MIME),因此无需指定它。 某些邮件客户端可能会限制你发送的文件类型,或者可能完全阻止附件。
使用 EmailMessage.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);
}
文件位置控制
重要
本部分仅适用于 Android。
在 Android 上的某些方案中,例如,当文件位于专用存储中时,可以将其复制到应用缓存中,然后通过 Android FileProvider
进行共享。 但是,这可能会无意中向攻击者暴露整个缓存和应用数据。 这可以通过在应用中添加一个文件提供者路径覆盖文件,并确保在共享之前将文件复制到该文件中指定的位置,从而防止出现此问题。
若要将文件提供程序文件路径替代文件添加到应用,请将名为 microsoft_maui_essentials_fileprovider_file_paths.xml 的文件添加到应用中的 Platforms\Android\Resources\xml 文件夹中。 因此,项目的完整相对文件名应 平台\Android\Resources\xml\microsoft_maui_essentials_fileprovider_file_paths.xml。 然后,为所需的路径将 XML 添加到文件中:
<?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>
有关文件提供程序路径的详细信息,请参阅 developer.android.com 上的 FileProvider。
在共享文件之前,应确保先将其写入到替代文件中某个位置中的 共享根 文件夹中:
// 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),
});
如果共享 URI 排除共享根目录,则可以验证文件是否正确共享。 例如,如果共享文件 <CacheDirectory>/sharing-root/mydata.txt 并且共享 URI content://com.companyname.overwritefileproviderpaths.fileProvider/internal_cache/sharing-root/mydata.txt
则文件提供程序未使用正确的路径。 如果共享 URI content://com.companyname.overwritefileproviderpaths.fileProvider/internal_cache/mydata.txt
,则文件提供程序正在使用正确的路径。
警告
共享文件时,如果收到 Java.Lang.IllegalArgumentException
,并且消息类似于“找不到包含 /data/data/com.companyname.overwritefileproviderpaths/cache/some-non-sharing-path/mydata.txt”的内容,则很可能是您正在共享超出了共享根的文件。
平台差异
并非所有 Android 电子邮件客户端都支持 EmailBodyFormat.Html,因为无法检测到这种情况,因此我们建议在发送电子邮件时使用 EmailBodyFormat.PlainText。