◆PROCESSING 逆引きリファレンス
カテゴリー:スマホ(AndroidMode)
Emailを送信するには(AndroidMode編)
【概要】
PROCESSINGにAndroidMode を導入する事で、PROCESSINGで開発したプログラムをAndroid端末上で動かす事ができるようになります。
AndroidModeの導入については「PROCESSINGをAndroid端末で動かすには(4.0版)」記事を参照してください。
Email(電子メール)は、もはや私達の仕事には欠かせないツールとなりました。EmailをPCで動作するPROCESSINGから送る方法については「Emailを送信するには(JavaMode編)」で紹介しました。
本記事では、AndroidModeでEmailを送信する方法について紹介したいと思います。
Android で Email を送信する方法はいくつか存在するのですが、今回は javamail-android というライブラリを利用します。
本当は Javaモードと同じ Apache Commons Email を利用したかったのですが、どうやらそのままでは利用できないようで、あえなく断念しました(汗)。
javamail-androidライブラリを利用するには、以下の手順でライブラリを入手し、セットアップしてください。
【準備】
ライブラリを入手する
まずは、公式サイトからライブラリを入手しましょう。
Google Code から、以下の3つのライブラリをダウンロードして下さい。
- additionnal.jar
- mail.jar
- activation.jar
PROCESSINGで利用できるようにする
まずPROCESSINGの標準エディタから「新規プロジェクト」を作成し、空で良いので一度保存します。
なお保存前に「ファイル→設定」で、スケッチブックの場所に「わかりやすいパス」が指定されている事を確認してください。
上記例なら、スケッチを保存すると「D:\processing-3.3.6\src」に「sketch_180826b」などのフォルダが作成され、空のプログラムソースファイルができあがります。
このフォルダ(D:\processing-3.3.6\src\sketch_180826b)配下に、code フォルダを作成してください。すでに存在する場合は作成しなくてもOKです。
続いて、上記でダウンロードした3つの jar ファイルを、code フォルダの中に複写します。
標準エディタを起動済みの場合は、一旦終了させて再起動してください。
またPROCESSINGをAndroidStudioで利用している人は、プロジェクトの適当な位置にダウンロードした jar ファイルを配置して、プロジェクトの依存関係に追加してください。
パーミッションを与える
Android で電子メールの送受信を行うプログラムを動作させるためには、インターネットへのアクセス権限が必要となります。
インターネットへのアクセス権限を与えるには、AndroidManifest.xml ファイルに以下の行を追記します。
1 |
<uses-permission android:name="android.permission.INTERNET" /> |
下記は、AndroidManifest.xml ファイルに権限を追記した様子です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.mslabo.processingsample1"> <!-- アクセス権限を与える --> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> |
標準エディタでコーディングしている人は、メニューから Android → Sketch Permissions を選択して開くダイアログボックスで、INTERNET にチェックをつけてください。
【詳細】
電子メールの送信手順
電子メールを送信するには、おおまかに以下の4つのステップで作業をします。
- 送信先となるメールサーバへのセッションを作成する
- 本文やタイトル部分を[テキストパート]として設定する
- ファイルを添付する場合は[ファイルパート]として設定する
- 宛先を作成し、本文と添付ファイルをまとめて送信する
以下で順番に説明しますが、メールサーバに Google を利用する場合で、かつ Googleへのログインに2段階認証を利用している場合は、通常のパスワードではなく別途アプリケーション用のパスワードを発行して、それを設定する必要があります。
アプリケーション用パスワードの発行については、以下のサイト様などが参考となります。
セッションを作成する
セッションを作成するには、まずはプロパティクラスを使ってプロパティインスタンスを作成し、必要な情報をセットします。
空のプロパティを作成Properties prop = new Properties();
prop : プロパティインスタンス
作成は簡単ですね。作成できたら、このプロパティにメールサーバへ接続するための情報をセットします。
.
プロパティをセットObject obj = prop.setProperty(String key,String value);
prop : プロパティインスタンス
key : プロパティ名
value : セットする値
obj : セットする前に key で設定されていた以前の値。ない場合は null
メール送信に関連する代表的なプロパティ名は以下になります。詳しくは以下のサイトなどを参照してください。
代表的なプロパティ名 | タイプ | 説明 |
---|---|---|
mail.smtp.host | String | SMTPで接続する相手ホスト名 |
mail.smtp.port | int | SMTPで接続する相手ポート番号 |
mail.smtp.auth | boolean | 認証機能を利用する場合 true にする |
mail.smtp.starttls.enable | boolean | 認証要求時にTLSを使う場合 true にする |
mail.smtp.socketFactory.class | String | SMTPに利用するソケットクラスを指定する。SSLを使うなら’javax.net.ssl.SSLSocketFactory’を与える |
mail.smtp.socketFactory.fallback | boolean | 上記で指定したクラスでソケット生成できない場合、デフォルト値を使うか否かの指定。SSLを使うなら、安全のため false にしておく |
以下は、SSLで Google のメールサーバに接続する設定例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//空のプロパティ作成 Properties props = new Properties(); // SMTPサーバーの設定。ここでは Google のsmtpサーバーをセット props.setProperty("mail.smtp.host", "smtp.gmail.com"); // SSL用にポート番号を変更。 props.setProperty("mail.smtp.port", "465"); // 認証ON props.setProperty("mail.smtp.auth", "true"); props.setProperty("mail.smtp.starttls.enable", "true"); // SSL接続指定 props.setProperty("mail.smtp.ssl.enable", "true" ); props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.setProperty("mail.smtp.socketFactory.fallback", "false"); |
.
プロパティに必要な値をセットしたら、セッションを作成します。
1 2 3 4 5 6 7 8 |
//propsに設定した情報を使用して、sessionを作成 Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( "[あたなのアカウント名]", "[あなたのパスワード]"); } }); |
セッションは Session クラスに、先程パラメータを設定したプロパティインスタンスと認証情報を与えて作成しますが、ほとんど上記のコーディングを丸コピーでOKです。
[あなたのアカウント名] と [あなたのパスワード] には、メールサーバに接続するための情報を書き込んでください。Googleの2段階認証利用時は、ここにアプリケーション用のパスワードを設定します。
テキストパートを作成する
MimeMessage を作成MimeMessage message = new MimeMessage(session);
session: セッション情報
message : MimeMessage インスタンス
メールの本文とタイトルをテキストパートとして作成します。
テキストだけのメールを送る場合は、MimeMessage クラスのインスタンスに直接本文とタイトルを設定する事も可能です。
例えば下記は、その例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//エンコード指定 final String ENCODE = "ISO-2022-JP"; // メッセージ内容の設定 MimeMessage message = new MimeMessage(session); try { // メールのSubject message.setSubject("メールのタイトル", ENCODE); // メール本文。 message.setText( "このメールはPROCESSINGから送られました。", ENCODE); } catch (MessagingException e) { e.printStackTrace(); } |
しかしテキストだけではなくてファイルを添付する場合や、HTML形式のメールを送る場合は、MimeMessage クラスのインスタンスに直接本文を設定するのではなく、[テキスト部分]、[HTML部分]、[ファイル添付部分] を、それぞれ分けて作成する必要があります。
.
テキストパートを作成MimeBodyPart txtPart = new MimeBodyPart();
txtPart : Bodyパート(この場合はテキストパート)
MimeBodyPart でBodyとなる部分を作成し、これに本文をセットします。
.
テキストパートに値を設定void txtPart.setText(String text, String charset);
void txtPart.setHeader(String name, String value);
txtPart : MimeBodyPart(この場合はテキストパート)
text : 本文
charset : エンコード指定。’ISO-2022-JP’や’UTF-8’を使用
name : メールヘッダに追加する名前
value : 追加する値
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
//エンコード指定 final String ENCODE = "ISO-2022-JP"; // メッセージ内容の設定 MimeMessage message = new MimeMessage(session); try { MimeBodyPart txtPart = new MimeBodyPart(); //【テキストパート】を作成 // タイトル message.setSubject("メールのタイトル", ENCODE); // 本文 txtPart.setText( "このメールはPROCESSINGから送られました。", ENCODE); // ファイル添付対策 txtPart.setHeader("Content-Transfer-Encoding", "base64"); } catch (MessagingException e) { e.printStackTrace(); } |
こんな感じですね。
Content-Transfer-Encoding は未設定でも構いませんが、ファイルなどを添付する場合は指定した方が良いでしょう。
ファイルパートを作成する
作り方はテキストパートと同じですが、添付するファイルを指定する箇所が少しばかり特殊です。
まず添付したいファイルのパスを取得し、それを元に FileDataSource() クラスのインスタンスを作成します。
続いてFileDataSource インスタンスを元に、DataHandler() クラスのインスタンスを作成し、出来上がったDataHandler インスタンスをファイルパートに添付します。
.
DataHandler を指定void filePart.setDataHandler(DataHandler dh);
void filePart.setFileName(String filename);
filePart : MimeBodyPart(この場合はファイルパート)
dh: DataHandler インスタンス
filename : ファイル名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// メッセージ内容の設定 MimeMessage message = new MimeMessage(session); try { //【ファイルパート】を作成 MimeBodyPart filePart = new MimeBodyPart(); // 添付情報設定 // ファイルのパスを取得 String path = getActivity().getFilesDir() + File.separator + "girl.jpg"; //FileDataSourceインスタンス作成 File file = new File(path); FileDataSource fds = new FileDataSource(file); //DataHandler インスタンス作成 DataHandler data = new DataHandler(fds); //ファイルパートに添付する filePart.setDataHandler(data); filePart.setFileName(MimeUtility.encodeWord("添付ファイルの名前")); } catch (MessagingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } |
filePart.setFileName() は必須ではありません。これを行うと、添付ファイルの名前を好きなものに変更可能です。
指定しないと、上記の例なら girl.jpg のままとなります。
宛先を指定し、各パートをまとめる
メールの送信宛先(FromとTo)を指定します。電子メールなので、宛先はInternetAddress クラスのインスタンスになります。
宛先情報は MimeMessage インスタンスにセットします。
.
宛先を指定void message.setFrom(Address from);
void message.addRecipients(Message.RecipientType type, Address[] to);
message : MimeMessage インスタンス
from: Fromアドレス
to : toアドレス
type : RecipientTypeクラスの定数を指定する。BCC、CC、TO が利用可能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// メッセージ内容の設定 MimeMessage message = new MimeMessage(session); try { //送信先設定 String from = "FROMメールアドレス"; String[] to = {"TOメールアドレス1", "TOメールアドレス2" }; //FROM message.setFrom(new InternetAddress(from)); //TO InternetAddress[] toAddress = new InternetAddress[to.length]; for (int i = 0; i < to.length; i++) { toAddress[i] = new InternetAddress(to[i]); message.addRecipient(Message.RecipientType.TO, toAddress[i]); } } catch (MessagingException e) { e.printStackTrace(); } |
こんな感じです。
ここまでできたら、テキストパートとファイルパートを1つにまとめます。
このように複数のパートから出来上がったメールの事をマルチパートメールと呼びますが、まとめるには MimeMultipart クラスを利用します。
.
宛先を指定Multipart mp = new MimeMultipart();
void mp.addBodyPart(BodyPart part);
mp : MimeMultipartインスタンス
part : まとめたいMimeBodyPartインスタンス
まとめる事ができたら、それをMimeMessage インスタンスにセットします。
.
宛先を指定void message.setContent(Multipart mp);
mp : MimeMultipartインスタンス
message : MimeMessageインスタンス
1 2 3 4 5 6 7 |
//各パートを1つにまとめる Multipart mp = new MimeMultipart(); mp.addBodyPart(txtPart); mp.addBodyPart(filePart); //MimeMessage インスタンスにセット message.setContent(mp); |
送信する
あとは電子メールを送信するだけです。電子メールの送信には、Transport クラスの send メソッドを利用します。
.
宛先を指定void Transport . send( Message msg );
msg : MimeMessageインスタンス
送信に失敗すると MessagingException 例外が発生します。
1 2 3 4 5 6 7 8 9 10 |
// メール送信 try { Transport.send(message); } catch (AuthenticationFailedException e) { // 認証失敗 e.printStackTrace(); } catch (MessagingException e) { // smtpサーバへの接続失敗 e.printStackTrace(); } |
【関連記事】
サンプルプログラム
シンプルなメール送信例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.Properties; import javax.mail.Session; /** * PROCESSING AndroidMode Email Send Sample * @auther MSLABO * @version 2018/08 1.0 */ private static final String ENCODE = "ISO-2022-JP"; void setup(){ fullScreen(); //空のプロパティ作成 Properties props = new Properties(); // SMTPサーバーの設定 props.setProperty("mail.smtp.host", "smtp.gmail.com"); // SSL用にポート番号を変更。 props.setProperty("mail.smtp.port", "465"); // 認証ON props.setProperty("mail.smtp.auth", "true"); props.setProperty("mail.smtp.starttls.enable", "true"); // SSL接続指定 props.setProperty("mail.smtp.ssl.enable", "true" ); props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.setProperty("mail.smtp.socketFactory.fallback", "false"); //propsに設定した情報を使用して、sessionの作成 Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( "[あなたのアカウント名]", "[あなたのパスワード]" ); } }); // メッセージ内容の設定 MimeMessage message = new MimeMessage(session); try { // メールのSubject message.setSubject("メールのタイトル", ENCODE); // メール本文。 message.setText( "このメールはPROCESSINGから送られました。", ENCODE); //送信先設定 String from = "[送信元メールアドレス]"; String[] to = {"[送信先メールアドレス]"}; //FROM message.setFrom(new InternetAddress(from)); //TO InternetAddress[] toAddress = new InternetAddress[to.length]; for (int i = 0; i < to.length; i++) { toAddress[i] = new InternetAddress(to[i]); message.addRecipient(Message.RecipientType.TO, toAddress[i]); } } catch (MessagingException e) { e.printStackTrace(); } // メール送信 try { Transport.send(message); } catch (AuthenticationFailedException e) { // 認証失敗 e.printStackTrace(); } catch (MessagingException e) { // smtpサーバへの接続失敗 e.printStackTrace(); } } void draw(){ background(255); } |
ファイルなどを添付しない、シンプルなテキストメールの送信例です。
ファイル添付送信例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.Properties; import javax.mail.Session; /** * PROCESSING AndroidMode Email Send Sample * @auther MSLABO * @version 2018/08 2.0 */ private static final String ENCODE = "ISO-2022-JP"; void setup(){ fullScreen(); //空のプロパティ作成 Properties props = new Properties(); // SMTPサーバーの設定 props.setProperty("mail.smtp.host", "smtp.gmail.com"); // SSL用にポート番号を変更。 props.setProperty("mail.smtp.port", "465"); // 認証ON props.setProperty("mail.smtp.auth", "true"); props.setProperty("mail.smtp.starttls.enable", "true"); // SSL接続指定 props.setProperty("mail.smtp.ssl.enable", "true" ); props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.setProperty("mail.smtp.socketFactory.fallback", "false"); //propsに設定した情報を使用して、sessionの作成 Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( "[あなたのアカウント名]", "[あなたのパスワード]" ); } }); // メッセージ内容の設定 MimeMessage message = new MimeMessage(session); try { //【テキストパート】を作成 MimeBodyPart txtPart = new MimeBodyPart(); // タイトル message.setSubject("メールのタイトル", ENCODE); // 本文 txtPart.setText( "このメールはPROCESSINGから送られました。", ENCODE, "plain"); //【ファイルパート】を作成 MimeBodyPart filePart = new MimeBodyPart(); // 添付情報設定 String path = dataPath("") + File.separator + "girl.png"; File file = new File(path); FileDataSource fds = new FileDataSource(file); DataHandler data = new DataHandler(fds); filePart.setDataHandler(data); filePart.setFileName(MimeUtility.encodeWord("添付ファイルの名前")); // 添付ファイル対策 filePart.setHeader("Content-Transfer-Encoding", "base64"); //送信先設定 String from = "[送信元メールアドレス]"; String[] to = {"[送信先メールアドレス]"}; //FROM message.setFrom(new InternetAddress(from)); //TO InternetAddress[] toAddress = new InternetAddress[to.length]; for (int i = 0; i < to.length; i++) { toAddress[i] = new InternetAddress(to[i]); message.addRecipient(Message.RecipientType.TO, toAddress[i]); } //各パートを1つにまとめる Multipart mp = new MimeMultipart(); mp.addBodyPart(txtPart); mp.addBodyPart(filePart); //MimeMessage インスタンスにセット message.setContent(mp); } catch (MessagingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } // メール送信 try { Transport.send(message); } catch (AuthenticationFailedException e) { // 認証失敗 e.printStackTrace(); } catch (MessagingException e) { // smtpサーバへの接続失敗 e.printStackTrace(); } } void draw(){ background(255); } |
マルチパートでファイルを添付しています。
あらかじめストレージのアプリケーション内部領域に、girl.png という名前のファイルがある事が前提となっています。ファイルがないと例外エラーになるので注意してください。
<出力サンプル>
(画像URL:illust-AC 様:MAKIPEN さん)
HTMLメール送信例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.Properties; import javax.mail.Session; /** * PROCESSING AndroidMode Email Send Sample * @auther MSLABO * @version 2018/08 3.0 */ private static final String ENCODE = "ISO-2022-JP"; void setup(){ fullScreen(); //空のプロパティ作成 Properties props = new Properties(); // SMTPサーバーの設定 props.setProperty("mail.smtp.host", "smtp.gmail.com"); // SSL用にポート番号を変更。 props.setProperty("mail.smtp.port", "465"); // 認証ON props.setProperty("mail.smtp.auth", "true"); props.setProperty("mail.smtp.starttls.enable", "true"); // SSL接続指定 props.setProperty("mail.smtp.ssl.enable", "true" ); props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.setProperty("mail.smtp.socketFactory.fallback", "false"); //propsに設定した情報を使用して、sessionの作成 Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( "[あなたのアカウント名]", "[あなたのパスワード]" ); } }); // メッセージ内容の設定 MimeMessage message = new MimeMessage(session); try { //【テキストパート】を作成 MimeBodyPart txtPart = new MimeBodyPart(); // タイトル message.setSubject("HTMLメール", ENCODE); // 本文 txtPart.setText( "このメールはPROCESSINGから送られました", ENCODE, "plain"); //【HTMLパート】を作成 // CIDはユニークなものに変更する事 String CID = "img_cid"; MimeBodyPart htmlPart = new MimeBodyPart(); htmlPart.setText("<!DOCTYPE html>" + "<html>" + "<head><title>HTMLメール</title></head>" + "<body>" + "<p>女の子</p>" + "<img src=cid:" + CID + ">" + "</body>" + "</html>", ENCODE, "html"); //【ファイルパート】を作成 MimeBodyPart filePart = new MimeBodyPart(); // 添付情報設定 String path = dataPath("") + File.separator + "girl.png"; File file = new File(path); FileDataSource fds = new FileDataSource(file); DataHandler data = new DataHandler(fds); filePart.setDataHandler(data); filePart.setFileName(MimeUtility.encodeWord("添付ファイルの名前")); //CIDでインライン指定 filePart.setHeader("Content-ID", "<" + CID + ">"); filePart.setDisposition(Part.INLINE); // 添付ファイル対策 filePart.setHeader("Content-Transfer-Encoding", "base64"); //送信先設定 String from = "[送信元メールアドレス]"; String[] to = {"[送信先メールアドレス]"}; message.setFrom(new InternetAddress(from)); InternetAddress[] toAddress = new InternetAddress[to.length]; for (int i = 0; i < to.length; i++) { toAddress[i] = new InternetAddress(to[i]); message.addRecipient(Message.RecipientType.TO, toAddress[i]); } //各パートを1つにまとめる Multipart mp = new MimeMultipart(); mp.addBodyPart(txtPart); mp.addBodyPart(htmlPart); mp.addBodyPart(filePart); //MimeMessage インスタンスにセット message.setContent(mp); } catch (MessagingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } // メール送信 try { Transport.send(message); } catch (AuthenticationFailedException e) { // 認証失敗 e.printStackTrace(); } catch (MessagingException e) { // smtpサーバへの接続失敗 e.printStackTrace(); } } void draw(){ background(255); } |
テキストパート、HTMLパート、画像ファイルパートの3部構成のメールです。画像ファイルは HTML の CID 指定でインライン埋め込みをしています。
これはサンプルですのでCIDが超適当(img_cid)です(汗)。実際に利用する際には、ユニークな CIDに変更してください。
<出力サンプル>
(画像URL:illust-AC 様:MAKIPEN さん)
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。