JavaMailでのメール送信まとめその4
JavaMailでのメール送信まとめその4。
AndroidアプリからJavamailでメール送信を行うサンプル。
Android端末専用のjarファイル(mail.jar、additionnal.jar、activation.jar)が必要ですが、MimeMessageの作成、送信手順は同じです。
また、Outbound Port 25 Blockingにより、25番ポートでメール送信が不可能なことがあるため、gmailのアカウントを使用して送信しています。
Android用JavaMailのダウンロード
android用のJavaMailを提供しているサイト「javamail-android」よりダウンロードします。
以下のjarファイルをダウンロードしてください。
- javamail-android
http://code.google.com/p/javamail-android/
-
- mail.jar
- additionnal.jar
- activation.jar
libsといったディレクトリを作成し、上記のjarファイルをコピーしてください。
その後、ビルドパスに追加すれば準備完了です。
(eclipseの場合は、jarファイルを右クリックした後、ビルドパスに追加を選択すればOKです。)
サンプル
gmailでメール送信
ネットワークアクセスが発生するため、パーミッションの設定が必要になります。
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
- gmail経由での送信サンプルコード
Properties props = new Properties(); props.put("mail.smtp.host", "smtp.gmail.com"); // SMTPサーバ名 props.put("mail.host", "smtp.gmail.com"); // 接続するホスト名 props.put("mail.smtp.port", "587"); // SMTPサーバポート props.put("mail.smtp.auth", "true"); // smtp auth props.put("mail.smtp.starttls.enable", "true"); // STTLS // セッション Session session = Session.getDefaultInstance(props); session.setDebug(true); MimeMessage msg = new MimeMessage(session); try { msg.setSubject("gmailでメール送信テスト(utf-8)", "utf-8"); msg.setFrom(new InternetAddress("Fromアドレス")); msg.setSender(new InternetAddress("Senderアドレス")); msg.setRecipient(Message.RecipientType.TO, new InternetAddress("送信先アドレス")); msg.setText("gmail経由でgmail.com向けメール送信テスト", "utf-8"); Transport t = session.getTransport("smtp"); t.connect("gmailアカウント XXXX@gmail.com", "gmailパスワード"); t.sendMessage(msg, msg.getAllRecipients()); } catch (MessagingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
携帯メール、デコメを送信
iPhone(i.softbank.jp)向けに送信してみます。
package com.ttshrk.send_mail_from_app; import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.NoSuchProviderException; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimeUtility; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import com.ttshrk.mbemoji.Emoji; import com.ttshrk.mbemoji.EmojiUtility; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.UnknownServiceException; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; public class SendMailFromApp extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button1 = (Button) findViewById(R.id.button1); button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { buttonClick1(); } }); Button button2 = (Button) findViewById(R.id.button2); button2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { buttonClick2(); } }); } /** * utf-8 softbank.ne.jp */ private void buttonClick1() { Session session = createSendGMailSession(); MimeMessage msg = new MimeMessage(session); try { msg.setSubject("gmailで携帯向けメール送信テスト(utf-8)", "utf-8"); msg.setFrom(new InternetAddress("from@example.com")); msg.setSender(new InternetAddress("from@example.com")); msg.setRecipient(Message.RecipientType.TO, new InternetAddress( "?????@i.softbank.jp")); msg.setDataHandler(new DataHandler(new TextBinaryDataSource( "gmail経由でi.softbank.jp向けメール送信テスト[:1025:][:0105:]" .getBytes(), "utf-8", "plain", Emoji.Mode.SOFTBANK))); sendGmail(msg, session); } catch (MessagingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * utf-8 i.softbank.jp でこめ * multipart/related * ├ multipart/alternative * │ ├ text/plain * │ └ text/html * └ image (インライン画像/添付画像) */ private void buttonClick2() { Session session = createSendGMailSession(); MimeMessage msg = new MimeMessage(session); try { msg.setSubject("gmailでメール送信テスト(utf-8) でこめ", "utf-8"); msg.setFrom(new InternetAddress("from@example.com")); msg.setSender(new InternetAddress("from@example.com")); msg.setRecipient(Message.RecipientType.TO, new InternetAddress( "?????@i.softbank.jp")); // related Multipart relatedPart = new MimeMultipart("related"); // alternative MimeBodyPart alternativeBodyPart = new MimeBodyPart(); Multipart alternativePart = new MimeMultipart("alternative"); alternativeBodyPart.setContent(alternativePart); relatedPart.addBodyPart(alternativeBodyPart); // text mail MimeBodyPart textBodyPart = new MimeBodyPart(); textBodyPart.setDataHandler(new DataHandler(new TextBinaryDataSource( "gmail経由でi.softbank.jp向けメール送信テスト[:1025:][:0105:]".getBytes(), "utf-8", "plain", Emoji.Mode.SOFTBANK))); textBodyPart.setHeader("Content-Transfer-Encoding", "base64"); alternativePart.addBodyPart(textBodyPart); // html mail MimeBodyPart htmlBodyPart = new MimeBodyPart(); htmlBodyPart.setDataHandler(new DataHandler(new TextBinaryDataSource( "<HTML><BODY>gmail経由でi.softbank.jp向けメール送信テスト[:1025:][:0105:]<IMG src=\"cid:12345@12345\"></BODY></HTML>".getBytes(), "utf-8", "html", Emoji.Mode.SOFTBANK))); htmlBodyPart.setHeader("Content-Transfer-Encoding", "base64"); alternativePart.addBodyPart(htmlBodyPart); // inline image MimeBodyPart imageBodyPart = new MimeBodyPart(); imageBodyPart.setDataHandler(new DataHandler(new FileDataSource("/sdcard/sample.gif"))); imageBodyPart.setFileName(MimeUtility.encodeWord("sample.gif")); imageBodyPart.setDisposition("inline"); // inline指定しておく imageBodyPart.setContentID("12345@12345"); // インライン画像を指定 relatedPart.addBodyPart(imageBodyPart); // set related msg.setContent(relatedPart); sendGmail(msg, session); } catch (MessagingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * * @return */ private Session createSendGMailSession() { Properties props = new Properties(); props.put("mail.smtp.host", "smtp.gmail.com"); // SMTPサーバ名 props.put("mail.host", "smtp.gmail.com"); // 接続するホスト名 props.put("mail.smtp.port", "587"); // SMTPサーバポート props.put("mail.smtp.auth", "true"); // smtp auth props.put("mail.smtp.starttls.enable", "true"); // STTLS // セッション Session session = Session.getDefaultInstance(props); session.setDebug(true); return session; } /** * * @param msg * @param session * @throws MessagingException */ private void sendGmail(MimeMessage msg, Session session) throws MessagingException { Transport t = session.getTransport("smtp"); t.connect("gmailユーザアカウント", "gmailパスワード"); t.sendMessage(msg, msg.getAllRecipients()); } } /** * 特定のコードをバイナリ絵文字に変換するDataSource */ class TextBinaryDataSource implements DataSource { private byte[] text; private byte[] convertedText; private String charset; private String subType; private Emoji.Mode emojiMode; public TextBinaryDataSource(byte[] text, String charset, String subType, Emoji.Mode emojiMode) throws IOException { this.text = text; this.charset = charset; this.subType = subType; this.emojiMode = emojiMode; initialize(); } public TextBinaryDataSource(String text, String charset, String subType, Emoji.Mode emojiMode) throws IOException { this(text.getBytes(), charset, subType, emojiMode); } public byte[] getPlainText() { return text; } private void initialize() throws IOException { InputStream dec_in = new ByteArrayInputStream(text); ByteArrayOutputStream bo = null; OutputStream os = null; try { bo = new ByteArrayOutputStream(); os = EmojiUtility.decode(bo, charset, emojiMode); byte[] buf = new byte[2048]; int len; while ((len = dec_in.read(buf)) != -1) { os.write(buf, 0, len); } } finally { if (os != null) { os.close(); } } convertedText = bo.toByteArray(); } @Override public InputStream getInputStream() throws IOException { InputStream is = new ByteArrayInputStream(convertedText); return is; } @Override public OutputStream getOutputStream() throws IOException { throw new UnknownServiceException(); } @Override public String getContentType() { return "text/" + subType + "; charset=" + charset; } @Override public String getName() { return ""; } }
デコメの部分の添付ファイルはSDカードから取得するようにしました。
(assetsから読み込む場合、「new InputStreamReader(context.getAssets().open("sample.gif"))」のようにして取得するため、InputStreamを設定できるDataSourceが必要らしいので・・・)
- サンプルコード
また、shift-jis、utf-8のコードで、ソフトバンク携帯アドレス(XXXX@softbank.ne.jp)、iPhone(i.softbank.jp)向けに送信してみたところ、どちらも送信はできましたが以下のような違いがありました。ただ、ちゃんと検証したわけではないので、目安程度にしてください。
(どちらのメールも、iPhone宛てに送信しました。)