在ios端mono开发中,发送邮件可以选择调用ios原生email程序。有两种方式实现这种功能,一是程序跳转到ipad中email程序,另外一种是将发送邮件的界面在自己应用里弹出。

首先第一种方式的代码:

    string sendEmail = "mailto:收件人邮箱地址?cc=发件人邮箱地址&subject=主题&body=邮件内容";
UIApplication.SharedApplication.OpenUrl(NSUrl.FromString(sendEmail));

这种方式会直接打开ipad本地email程序,但这种方式有个缺点是无法传送附件,并且会离开当前应用。

第二种方式,是可以发送附件并且可以在本应用中进行,mono中已经有封装好的类MFMailComposeViewController去调用。

如果你ipad未设置邮箱账户,或者你的邮箱账户在设置里未显示激活状态,则直接弹出此窗体会报错。所以在调用代码的时候,要先判断MFMailComposeViewController.CanSendMail是否为true,如果为false的话,可以通过用第一种方式把设置邮箱账户的界面弹出来。在发送的时候,通过读取保存在xml中的收件人信息,设置本次收件人的地址,这样用户就不需要每次都填写收件人了。具体代码如下:

        /// <summary>
/// 发送邮件
/// </summary>
/// <param name="subject">邮件主题.</param>
/// <param name="messageBody">邮件内容</param>
protected void SendEmail(string subject, string messageBody) {
//首先判断是否能发送邮件,如果邮箱里已经设置邮箱账户,并激活则为true
//模拟器里为true
if (!MFMailComposeViewController.CanSendMail) {
MFMailComposeViewController mf = new MFMailComposeViewController();
mf.MailComposeDelegate = new MailComposeDelegate(); //设置发送完成后的委托事件
mf.SetSubject(subject);// 设置邮件主题
#region 获取上次发送邮件后保存在xml中的收件人
XmlDocument xmlDoct = new XmlDocument();
string xmlpath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "SysConfiguration.xml");
xmlDoct.Load(xmlpath);
if (xmlDoct != null) {
XmlNode xmlNodeContinue = xmlDoct.SelectSingleNode("Configuration/MailReceiver");
if (xmlNodeContinue != null) {
string strReceiver = xmlNodeContinue.InnerText;
mf.SetToRecipients(strReceiver.Split(',')); //设置收件人
}
}
#endregion;
mf.SetMessageBody("说明: 请下载附件进行打印 ", true); //设置邮件内容
#region 设置附件
NSData data = NSData.FromString(messageBody, NSStringEncoding.UTF8);
mf.AddAttachmentData(data, @"text/html", subject + ".html");
#endregion
//弹出发送邮件窗体
this.PresentModalViewController(mf, true);
} else {
Tapku.TKAlertCenter.DefaultCenter.PostAlert("无发件人,请先在系统设置里添加邮箱账户");
//这里也会调用ipad email应用 弹出设置邮箱账户的窗体
string sendEmail = "mailto:xianchagnzhifa@163.com";
UIApplication.SharedApplication.OpenUrl(NSUrl.FromString(sendEmail));
}
}

这时候点击发送或者取消,将会触发邮件完成事件,在完成的时候,通过递归遍历MFMailComposeViewController 中的控件(均继承自UIView),找到收件人的UITextField,保存收件人的地址到xml。

递归遍历代码:

///设置发送完成后的委托事件
class MailComposeDelegate:MFMailComposeViewControllerDelegate {
static string strReceiver = string.Empty;
//保存收件人的Email地址
void FindUITextField(UIView view) {
if (view is UITextField) {
//找到发件人的UITextField控件
if ((view as UITextField).Text.Contains("@")) {
strReceiver = (view as UITextField).Text;
}
return;
}
if (view.Subviews.GetCount() > 0) {
foreach (UIView subView in view.Subviews) {
//进行递归遍历
FindUITextField(subView);
}
}
}
///发送邮件或取消发送后的完成事件
public override void Finished(MFMailComposeViewController controller, MFMailComposeResult result, NSError error) { }
}

保存收件人并响应完成发送具体事件的操作实现代码如下:

           ///发送邮件或取消发送后的完成事件
public override void Finished(MFMailComposeViewController controller, MFMailComposeResult result, NSError error) {
//如果邮件发送成功,保存此次收件人的信息
if (result == MFMailComposeResult.Sent) {
FindUITextField(controller.View);//递归得到收件人Email地址
//保存本次发件人的地址
if (!string.IsNullOrEmpty(strReceiver)) {
XmlDocument xmlDoct = new XmlDocument();
string xmlpath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "SysConfiguration.xml");
xmlDoct.Load(xmlpath);
if (xmlDoct != null) {
XmlNode xmlNodeContinue = xmlDoct.SelectSingleNode("Configuration/MailReceiver");
if (xmlNodeContinue != null) {
xmlNodeContinue.InnerText = strReceiver;
xmlDoct.Save(xmlpath);
}
}
}
}
string message = string.Empty;
bool flag = false;
switch (result) {
case MFMailComposeResult.Cancelled:
message = "邮件未保存到草稿箱";
flag = true;
break;
case MFMailComposeResult.Failed:
message = "发送失败:" + error.ToString();
break;
case MFMailComposeResult.Saved:
message = "已保存到草稿箱";
flag = true;
break;
case MFMailComposeResult.Sent:
message = "发送成功";
flag = true;
break;
default:
break;
}
if (!string.IsNullOrEmpty(message)) {
Tapku.TKAlertCenter.DefaultCenter.PostAlert(message);
}
if (flag) {
//关掉发送邮件的窗体
controller.DismissModalViewControllerAnimated(true);
}
}
}

另外在mono中如果想读取和修改xml,不能讲xml文件放在程序目录文件夹里面,要把它copy到系统个人文件夹下面,应该是苹果权限控制的比较死的原因。具体操作代码如下:每次程序启动的时候会执行检测文件是否存在,不存在则拷贝到personal文件夹下面。

      string SystemSetPath=System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),"SysConfiguration.xml");
if(!System.IO.File.Exists(SystemSetPath))
{
System.IO.File.Copy("SysConfiguration.xml",SystemSetPath);
}

本次xml的结构如下:

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>
<MailReceiver></MailReceiver>
</Configuration>

另外,附件(html格式)发送到qq邮箱,预览时会乱码!在大神(博客地址)的帮助下,解决了这个问题!解决方案如下:

然后在发送邮件的时候,附件相关代码要这样改动:

NSData data = NSData.FromString(messageBody, NSStringEncoding.UTF8);
//替换为
byte[] messageBytes=System.Text.Encoding.GetEncoding("GB2312").GetBytes(messageBody);
NSData data = NSData.FromArray(messageBytes);

喜欢这篇文章就推荐下吧!您的支持是我继续的最大动力!

mono中发送邮件并保存本次收件人的地址的更多相关文章

  1. 在ASP.NET MVC 4 on Mono中使用OracleClient in CentOS 6.x的问题记录

    在ASP.NET MVC 4 on Mono中使用OracleClient in CentOS 6.x的问题记录 前言 最近有个Web项目,业务功能不复杂,但是这个客户(某政府部门)有两个硬性要求:1 ...

  2. JavaMail应用--通过javamail API实现在代码中发送邮件功能

    JavaMail应用   在日常开发中,可能会引用到发邮件功能,例如在持续集成中,自动化测试运行完毕,自动将测试结果以报表的形式发送邮件给相关人.那么在Java中如何实现发邮件呢? 在java EE ...

  3. 【matlab】将matlab中数据输出保存为txt或dat格式

    将matlab中数据输出保存为txt或dat格式 总结网上各大论坛,主要有三种方法. 第一种方法:save(最简单基本的) 具体的命令是:用save *.txt -ascii x x为变量 *.txt ...

  4. php获取网页中图片并保存到本地

    php获取网页中图片并保存到本地的代码,将网页中图片保存本地文件夹: save_img("http://www.jbxue.com" ?>

  5. php获取网页中图片并保存到本地的代码

    php获取网页中图片并保存到本地的代码,将网页中图片保存本地文件夹: <?php /** * 获取网页中图片,并保存至本地 * by www.jbxue.com */ header(" ...

  6. 实现app上对csdn的文章查看,以及文章中图片的保存 (制作csdn app 完结篇)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24022165 今天给大家带来CSDN的完结篇,即增加文章的查看和文章中图片的保存 ...

  7. .NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常)

    .NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常) 前段时间项目使用一次性读去SQL Server中保存的电子文件的文件流然后返回给客户端保存下载电子文件, ...

  8. Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上)

    原文:[置顶] Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上) 我们在用手机的时候可能会发现,即使应用被放到后台再返回到前台数据依然保留(比如说我们正在玩游戏,突然电话 ...

  9. Android菜鸟的成长笔记(15)—— Android中的状态保存探究(下)

    原文:Android菜鸟的成长笔记(15)-- Android中的状态保存探究(下) 在上一篇中我们简单了解关于Android中状态保存的过程和原理,这一篇中我们来看一下在系统配置改变的情况下保存数据 ...

随机推荐

  1. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  2. C语言 · 4_2找公倍数

    问题描述 这里写问题描述. 打印出1-1000所有11和17的公倍数. 样例输入 一个满足题目要求的输入范例.例:无 样例输出 与上面的样例输入对应的输出.例:   代码如下: #include< ...

  3. ASP.NET Core应用中如何记录和查看日志

    日志记录不仅对于我们开发的应用,还是对于ASP.NET Core框架功能都是一项非常重要的功能特性.我们知道ASP.NET Core使用的是一个极具扩展性的日志系统,该系统由Logger.Logger ...

  4. nodejs操作arduino入门(javascript操作底层硬件)

    用Javascript来操作硬件早就不是一件稀奇的事情了. 所以作为一名电子专业出身的FE,我也打算尝试一下用js来驱动arduino: 要想操作这些底层硬件,肯定是需要一些工具的,我这里介绍的工具主 ...

  5. STM32F429 LCD程序移植

    STM32F429自带LCD驱动器,这一具有功能给我等纠结于屏幕驱动的程序员带来了很大的福音.有经验的读者一定有过这样的经历,用FSMC驱动带由控制器的屏幕时候,一旦驱动芯片更换,则需要重新针对此驱动 ...

  6. Dynamics CRM 2015-Data Encryption激活报错

    在CRM的日常开发中,Data Encryption经常是不得不开启的一个功能.但是有时,我们可能遇到一种情况,Organization导入之后,查看Data Encryption是已激活的状态,但是 ...

  7. Android中Fragment和ViewPager那点事儿(仿微信APP)

    在之前的博文<Android中使用ViewPager实现屏幕页面切换和引导页效果实现>和<Android中Fragment的两种创建方式>以及<Android中Fragm ...

  8. 全网独家MongoDB Certified DBA Associate考试认证视频

    该视频意在让所有学员一次通过考试,避免重复考试而承担的巨额考试费用! 目前MongDB发展迅猛,有赶超mysql,和oracle看齐的苗头.在这个时候MongoDB也适时的推出了官方的认证考试&quo ...

  9. windows下mongodb配置

    打开cmd(windows键+r输入cmd)命令行,进入D:\mongodb\bin目录(如图先输入d:进入d盘然后输入cd d:\mongodb\bin), 输入如下的命令启动mongodb服务: ...

  10. NV显卡Ubuntu14.04更新软件导致登录死循环,不过可以进入tty模式

    注意:此方法只适用于nv显卡的电脑! 在网上寻找各种方法无果的情况下,选择重新安装显卡驱动,成功登录进入图形界面. 一.首先需要在另外一台电脑(windows系统也可以)上下载NVIDIA相应显卡驱动 ...