記事一覧

メールを送信する方法 | Xamarin.Forms


今回はXamarinでメールを送信する方法についてご紹介いたします。
iOSとAndroidで同じ呼び出しコードにするため、毎度お馴染みDependencyServiceでの記述になりますが、Androidでは少し気を付ける点があります。

Android5
xamarin_mail_01.jpg
Android4
xamarin_mail_02.jpg



前提条件
・Windows10
・Visual Studio 2015 Community Update3
・Xamarin 4.3.0.784 (NuGet Xamarin.Forms 2.3.4.224)
・macOS Sierra 10.12.4 / Xcode8.3.1 / Xamarin.iOS 10.4.0.123



1.PCLの記述方法

IMailService.cs
namespace AppName.Services
{
public interface IMailService
{
    bool StartMailer(string title, string body, string[] to, string[] cc, string[] bcc, string filePath, ref string err);
}
}



2.Androidでの記述方法

(1)intent.SetType("message/rfc822"); の記述を先頭で記述すると動作しませんでした。
(2)intent.SetData(Android.Net.Uri.Parse("mailto:" + to)); の記述をするほうが対応メーラーが広がるそうです。
(3)添付ファイルを付ける場合は、Android.Net.Uri.FromFile で添付することがより多くのメーラーとの相性が良くなるらしいです。

MailService.cs
using System;
using Android.Content;
using Xamarin.Forms;
using AppName.Services;
using AppName.Droid.Services;
[assembly: Dependency(typeof(MailService))]
namespace AppName.Droid.Services
{
public class MailService : IMailService
{
    public bool StartMailer(string title, string body, string[] to, string[] cc, string[] bcc, string filePath, ref string err)
    {
        try
        {
            //初期化
            err = String.Empty;

            var intent = new Intent();

            //アクションにACTION_SENDを指定して暗黙的インテントを呼び出すことで、
            //インストールされているアプリで対応可能なものが列挙されます。
            intent.SetAction(Intent.ActionSend);
            intent.AddFlags(ActivityFlags.NewTask);

            //項目セット
            intent.SetData(Android.Net.Uri.Parse("mailto:" + to));
            if (to != null && to.Length > 0)
            {
                intent.PutExtra(Intent.ExtraEmail, to);
            }
            if (cc != null && cc.Length > 0)
            {
                intent.PutExtra(Intent.ExtraCc, cc);
            }
            if (bcc != null && bcc.Length > 0)
            {
                intent.PutExtra(Intent.ExtraBcc, bcc);
            }
            intent.PutExtra(Intent.ExtraSubject, title);
            intent.PutExtra(Intent.ExtraText, body);

            if (String.IsNullOrEmpty(filePath))
            {
                //ファイル添付なし
                //intent.SetType("text/plain");
                intent.SetType("message/rfc822");
            }
            else
            {
                //ファイル添付あり
                intent.SetType("message/rfc822");
                Java.IO.File sendFile = new Java.IO.File(filePath);
                intent.PutExtra(Intent.ExtraStream, Android.Net.Uri.FromFile(sendFile));
            }

            //メーラー起動
            Forms.Context.StartActivity(intent);

        }
        catch (Exception ex)
        {
            err = ex.Message;
            Console.WriteLine(ex.Message + System.Environment.NewLine + ex.StackTrace);
            return false;
        }
        return true;
    }
}
}



3.iOSでの記述方法

MailService.cs
using Foundation;
using UIKit;
using MessageUI;
using Xamarin.Forms;
using AppName.iOS.Services;
using AppName.Services;
[assembly: Dependency(typeof(MailService))]
namespace AppName.iOS.Services
{
public class MailService : IMailService
{
public bool StartMailer(string title, string body, string[] to, string[] cc, string[] bcc, string filePath, ref string err)
{
//初期化
err = String.Empty;
string ret = String.Empty;

if (!MFMailComposeViewController.CanSendMail)
{//メール送信が可能かどうかの確認
err = "この端末はメールが送信可能な状態にありません。";
return false ; //メール送信不能
}

var mail = new MFMailComposeViewController();//インスタンスの生成

//項目セット
if (to != null && to.Length > 0)
{
mail.SetToRecipients(to);
}
if (cc != null && cc.Length > 0)
{
mail.SetCcRecipients(cc);
}
if (bcc != null && bcc.Length > 0)
{
mail.SetBccRecipients(bcc);
}
mail.SetSubject(title);
mail.SetMessageBody(body, false);

if (!String.IsNullOrEmpty(filePath))
{
//ファイル添付あり

//拡張子
string extention = System.IO.Path.GetExtension(filePath.ToLower()).Replace(".", "");
if (String.IsNullOrEmpty(extention))
{
//拡張子が取得できない場合はテキストで開く
extention = "txt";
}
//mime type
string mimetype = MimeTypeUtility.GetMimeType(extention);

NSData data = NSData.FromFile(filePath);
mail.AddAttachmentData(data, mimetype, System.IO.Path.GetFileName(filePath));
}

mail.Finished += (o, args) => {
//送信処理終了時のイベント
ret = args.Result.ToString(); // srgs.Result:戻り値
args.Controller.DismissViewController(true, null); //Eメール画面の消去
};

//メーラー起動
var view = UIApplication.SharedApplication.KeyWindow.RootViewController;
view.PresentViewController(mail, true, null);
err = ret;
return true;
}
}
}

※拡張子からMimeTypeを取得する方法(MimeTypeUtility.GetMimeType)につきましては以下のURLにてご紹介しております。
http://itblogdsi.blog.fc2.com/blog-entry-175.html



4.使用方法

SendMailPage.xaml.cs
async void OnSendMailButtonPress()
{
    string errMsg = String.Empty;
    DependencyService.Get<IMailService>().StartMailer("タイトル", "本文", null, null, null, this.txtFilePath, ref errMsg);;
    if (String.IsNullOrEmpty(errMsg))
    {
        await this.DisplayAlert("メール送信完了",
                                "メール送信完了しました。" + System.Environment.NewLine +
                                errMsg, "OK");
    }
    else
    {
        await this.DisplayAlert("メール送信失敗",
                                "メールが送信できませんでした。" + System.Environment.NewLine +
                                errMsg, "OK");
    }
}




当ブログの内容をまとめた Xamarin逆引きメニュー は以下のURLからご覧になれます。
http://itblogdsi.blog.fc2.com/blog-entry-81.html


関連記事

コメント

実装について
いつも拝読させて頂いてます。
ありがとうございます。
このページのメールの設定についてなのですが、これはMain.xaml.csやMainActivity.csの他にクラスを作ってDependencyServiceを使うということなのでしょうか。
はじめのPCLチェックでプロジェクトを展開した状態から具体的にどこを変えていけばいいかよくわからなくてすいません。
もしよろしければ教えてください。
よろしくお願い致します。
PS:応援してますe-68
Re: 実装について
コメントありがとうございます。

はい。そのとおりでございます。

通常、実行の主体となるプロジェクトのiOSプロジェクトとAndroidプロジェクトは、PCLプロジェクトを参照設定していますので、PCLプロジェクト内のクラスを呼び出すことができますが、逆の呼び出し方法(PCLから参照先)は今まではできませんでした。
それを可能にするのがDependencyServiceです。

今回の場合ですと、IMailService.csをPCL内に配置します。場所はどこでも構いませんが、DependencyServiceの利用率が多いので一か所のフォルダに固めておくとネームスペースの関係上、利用しやすいでしょう。これが無いと呼び出すことができません。

次に、Androidプロジェクト内にMailService.csを実装します。(当記事をコピペするだけです)
iOSプロジェクト内にもMailService.csを実装します。(当記事をコピペするだけです)

呼び出しはPCLでも可能ですし、実はPCL以外でもXamarin.Forms.Init()を呼び出した後であればどこからでも呼び出せます。
Main.xaml.csからページ遷移して "お問合せPage.xaml.cs"等で呼び出しすると良いでしょう。
コメントの投稿

広告

プロフィール

石河 純


著者名 :石河 純
自己紹介:素人上がりのIT技術者。趣味は卓球・車・ボウリング

IT関連の知識はざっくりとこんな感じです。
【OS関連】
WindowsServer: 2012/2008R2/2003/2000/NT4
Windows: 10/8/7/XP/2000/me/NT4/98
Linux: CentOS RedHatLinux9
Mac: macOS Sierra 10.12 / OSX Lion 10.7.5 / OSX Snow Leopard 10.6.8
【言語・データベース】
VB.net ASP.NET C#.net Java VBA
Xamarin.Forms
Oracle10g SQLServer2008R2 SQLAnywhere8/11/16
ActiveReport CrystalReport ReportNet(IBM)
【ネットワーク関連】
CCNP シスコ技術者認定
Cisco Catalyst シリーズ
Yamaha RTXシリーズ
FireWall関連
【WEB関連】
SEO SEM CSS IIS6/7 apache2

休みの日は卓球をやっています。
現在、卓球用品通販ショップは休業中です。