androidアプリ開発でメールを自動送信させる方法
概要
androidアプリにメールを送らせる方法は2つある。ひとつはintentを使ってメーラーを起動させる方法。もうひとつはjava mailを使って自動送信させる方法だ。
既存のメーラーに処理を渡すやり方は簡単だけど、ユーザーに送信ボタンを押してもらう必要があり、またandroid端末に付属するメーラーによって挙動が違うことがある。
一方、java mailライブラリを使うやり方はプログラムが面倒臭い。だけどユーザーに手間を掛けさせることなく、アプリが自動的にメールを送信してくれる。今回は後者の方法を説明する。
手順
1.java mailライブラリをダウンロードする
下記のサイトから「activation.jar」「additionnal.jar」「mail.jar」をダウンロードする。
javamail-android - JavaMail port for the android plateform - Google Project Hosting
2.java mailライブラリをeclipseプロジェクトに配置する
eclipseのlibフォルダに「activation.jar」「additionnal.jar」「mail.jar」をドラッグ&ドロップして配置する。
コピーするかリンクするか聞かれるので、「copy files」を選択する。
3.マニフェストにパーミッションを追加する
「AndroidManifest.xml」にインターネット通信権限を追加する。当然ながら、これがないとメール送信できない。
<uses-permission android:name="android.permission.INTERNET" />
4.androidアプリのプログラムを書く
まずはメールの送信部分。「修正」とコメントされている部分はご自分の環境に合うように変更してください。
public class MailSender { private Properties properties; public MailSender(){ properties = System.getProperties(); } public void send(){ properties.put("mail.smtp.host", "smtp.host.com"); // ←修正 properties.put("mail.smtp.port", "587"); properties.put("mail.smtp.auth", "true"); properties.put("mail.smtp.starttls.enable", "true"); Session session = Session.getDefaultInstance(properties, new javax.mail.Authenticator(){ protected PasswordAuthentication getPasswordAuthentication(){ return new PasswordAuthentication("info@hoge.com", "hogehoge"); // ←修正 } }); MimeMessage message = new MimeMessage(session); try { String from = "info@hoge.com"; // ←修正 String[] to = {"to@hoge.com"}; // ←修正 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]); } for(int i = 0; i < toAddress.length; i++){ message.addRecipient(Message.RecipientType.TO, toAddress[i]); } message.setSubject("メールのタイトル"); // ←修正 message.setText("メールの本文"); // ←修正 Transport.send(message); } catch (AddressException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } } }
これを呼び出すには下記のようなコードを書く。
MailSender ms = new MailSender(); ms.send();
・・・が、次のエラーが出た。
01-04 05:51:39.914: D/my app(32699): android.os.NetworkOnMainThreadException 01-04 05:42:24.504: W/System.err(26066): javax.mail.AuthenticationFailedException 01-04 05:42:24.504: W/System.err(26066): at javax.mail.Service.connect(Service.java:319) 01-04 05:42:24.504: W/System.err(26066): at javax.mail.Service.connect(Service.java:169) 01-04 05:42:24.504: W/System.err(26066): at javax.mail.Service.connect(Service.java:118) 01-04 05:42:24.504: W/System.err(26066): at javax.mail.Transport.send0(Transport.java:188) 01-04 05:42:24.504: W/System.err(26066): at javax.mail.Transport.send(Transport.java:118) 01-04 05:42:24.504: W/System.err(26066): at com.kawaidesu.mail.MainActivity$MailSender.send(MainActivity.java:138) 01-04 05:42:24.504: W/System.err(26066): at com.kawaidesu.mail.MainActivity$AsyncHttpRequest.doInBackground(MainActivity.java:86) 01-04 05:42:24.504: W/System.err(26066): at com.kawaidesu.mail.MainActivity$AsyncHttpRequest.doInBackground(MainActivity.java:1) 01-04 05:42:24.504: W/System.err(26066): at android.os.AsyncTask$2.call(AsyncTask.java:288) 01-04 05:42:24.504: W/System.err(26066): at java.util.concurrent.FutureTask.run(FutureTask.java:237) 01-04 05:42:24.504: W/System.err(26066): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 01-04 05:42:24.504: W/System.err(26066): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 01-04 05:42:24.504: W/System.err(26066): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 01-04 05:42:24.504: W/System.err(26066): at java.lang.Thread.run(Thread.java:841)
androidアプリでは、メインスレッドにネットワーク(HTTP)通信の処理を入れることは出来ないらしい。仕方ないので非同期スレッドを用意して、そのスレッド内でメール送信処理をする。
public class AsyncHttpRequest extends AsyncTask<Uri.Builder, Void, String> { @SuppressLint("UnlocalizedSms") @Override protected String doInBackground(Builder... params) { try { // ----- メール送信 MailSender ms = new MailSender(); ms.send(); } catch (Exception e) { return e.toString(); } return null; } @Override protected void onPostExecute(String result) { Toast.makeText(getBaseContext(), "メールを送信しました", Toast.LENGTH_SHORT).show(); } }
最後に、ボタンクリックなどのイベント内で非同期スレッドを起動するプログラムを書く。
public void onClick(View v) { switch(v.getId()){ case R.id.button1: // ----- 非同期通信 Uri.Builder builder = new Uri.Builder(); AsyncHttpRequest task = new AsyncHttpRequest(); task.execute(builder); } }
以上ですー。
「ソースコード見た方が早いよ!」という人のために、GitHubにサンプルプロジェクトをアップロードしておきました。そちらもどうぞ。