ssCAROのブログ

色んなとこで見つけたプログラムのメモ置き場っぽい

au-oneメールの送受信

Androidau-oneメールを送受信してみた。

  • 件名を空白で受信すると本文に<連番>: <件名>が表示される
  • 件名に<連番>を入れて受信すると本文が表示される

送信は絵文字入りの送信が出来なかった(相手側で見れない)。
Subjectは絵文字入りでも送信できてる見たい?

JISConverter.java は以下のURLを参考にしました。
http://sato0408.blog31.fc2.com/blog-date-20110526.html

"KDDIShiftJIStoUnicode"は以下のURLを参考にしました。
http://d.hatena.ne.jp/perezvon/20080910/1221026285

AuoneMailDemo.java

package com.example.android.AuoneMailDemo;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class AuoneMailDemoActivity extends Activity {
    private Button buttonSend;
    private Button buttonRecv;
    private EditText editSubject;
    private EditText editBody;

    private String mUser = "*****@auone.jp";
    private String mPassword = "*****";

    private String mFrom = "*****@ezweb.ne.jp";
    private String mTo = "*****@ezweb.ne.jp";
    private String mTargetFolder = "INBOX";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        buttonSend = (Button)findViewById(R.id.buttonSend);
        buttonSend.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                buttonSend_onClick();
            }
        });

        buttonRecv = (Button)findViewById(R.id.buttonRecv);
        buttonRecv.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                buttonRecv_onClick();
            }
        });

        editSubject = (EditText)findViewById(R.id.editSubject);
        Bundle bundleSubject = editSubject.getInputExtras(true);
        bundleSubject.putBoolean("allowEmoji", true);

        editBody = (EditText)findViewById(R.id.editBody);
        Bundle bundleBody = editBody.getInputExtras(true);
        bundleBody.putBoolean("allowEmoji", true);
    }

    public void buttonSend_onClick() {
        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.host", "smtp.gmail.com");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.starttls.enable", "true");

        try {
            final MimeMessage mimeMsg = new MimeMessage(Session.getDefaultInstance(props, new Authenticator() {
                @Override
                // 認証データ。アカウント名とパスワードを指定して下さい。
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(mUser, mPassword);
                }
            }));

            // 絵文字入りのメールが送れない
            String subject = editSubject.getText().toString();
            String body = editBody.getText().toString();

            mimeMsg.setFrom(new InternetAddress(mFrom));
            mimeMsg.setRecipients(MimeMessage.RecipientType.TO, InternetAddress.parse(mTo));
            mimeMsg.setSubject(subject);
            mimeMsg.setText(body);
            mimeMsg.setHeader("Content-Type", "text/plain; charset=iso-2022-jp");
            mimeMsg.setHeader("Content-Transfer-Encoding", "7bit");

            try {
                Transport.send(mimeMsg);
            } catch (MessagingException e) {
                throw new RuntimeException(e);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void buttonRecv_onClick() {
        String num = editSubject.getText().toString();

        if (num.equals("")) {
            viewSubject();
        } else {
            int mailNo = 0;
            try {
                mailNo = Integer.parseInt(num);
                if (mailNo > 0) {
                    viewBody(mailNo);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    private void viewSubject() {
        Properties props = new Properties();
        props.setProperty("mail.store.protocol", "imaps");
        //props.setProperty("mail.imap.host", "imap.gmail.com");
        //props.setProperty("mail.imap.port", "993");
        //props.setProperty("mail.imap.socketFactory.port", "993");
        //props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        //props.setProperty("mail.imap.socketFactory.fallback", "false");
        //props.setProperty("mail.imap.connectionpoolsize", "10");
        //props.setProperty("mail.imap.separatestoreconnection", "true");
        //props.setProperty("mail.imap.partialfetch", "false");

        Session sess = Session.getDefaultInstance(props, null);
        Store store = null;
        Folder folder = null;

        try {
            store = sess.getStore("imaps");
            store.connect("imap.gmail.com",
                          993,
                          mUser,
                          mPassword);

            folder = store.getFolder(mTargetFolder);
            folder.open(Folder.READ_ONLY);

            int totalMessages = folder.getMessageCount();
            Message[] messages = folder.getMessages();
            StringBuffer sb = new StringBuffer();
            String subject = "";
            sb.append("件名に番号を入れて受信で本文表示\n");
            for (int i = 0; i < totalMessages; i++) {
                Message message = messages[i];
                if (message.isMimeType("text/plain")) {
                    subject = String.format("%d: %s\n", i+1, message.getSubject());
                    sb.append(subject);
                }
            }
            editBody.setText(sb.toString());
            // フォルダーを閉じます
            folder.close(false);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (store != null) {
                    store.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void viewBody(int index) {
        Properties props = new Properties();
        props.setProperty("mail.store.protocol", "imaps");
        //props.setProperty("mail.imap.host", "imap.gmail.com");
        //props.setProperty("mail.imap.port", "993");
        //props.setProperty("mail.imap.socketFactory.port", "993");
        //props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        //props.setProperty("mail.imap.socketFactory.fallback", "false");
        //props.setProperty("mail.imap.connectionpoolsize", "10");
        //props.setProperty("mail.imap.separatestoreconnection", "true");
        //props.setProperty("mail.imap.partialfetch", "false");

        Session sess = Session.getDefaultInstance(props, null);
        Store store = null;
        Folder folder = null;

        try {
            store = sess.getStore("imaps");
            store.connect("imap.gmail.com",
                          993,
                          mUser,
                          mPassword);

            folder = store.getFolder(mTargetFolder);
            folder.open(Folder.READ_ONLY);

            Message message = folder.getMessage(index);

            if (message.isMimeType("text/plain")) {

                editSubject.setText(message.getSubject());

                String body = getBody(message);

                editBody.setText(body);
            }

            // フォルダーを閉じます
            folder.close(false);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (store != null) {
                    store.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private String getBody(Message message) {
        StringBuffer sbRet = new StringBuffer();
        try {
            InputStream is = message.getDataHandler().getInputStream();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            OutputStream outputStream = new BufferedOutputStream(byteArrayOutputStream);
            int c;
            while ((c = is.read()) != -1) {
                outputStream.write(c);
            }
            outputStream.flush();
            outputStream.close();
            byte[] b = byteArrayOutputStream.toByteArray();

            StringBuffer sbSjis = JISConverter.toSJIS(b);

            int len = sbSjis.length();

            for (int k = 0; k < len; k++) {
                char ch = sbSjis.charAt(k);
                // 半角
                if (ch < 0x80) {
                    sbRet.append(ch);
                // 半角かな
                } else if (0xa1 <= ch && ch <= 0xdf) {
                    sbRet.append(ch);
                // 漢字
                } else {
                    k++;
                    // 半角扱い
                    if (k >= len) {
                        sbRet.append(ch);
                    }
                    char ch2 = sbSjis.charAt(k);
                    int code = ch << 8 | ch2;
                    // 絵文字範囲(Shift_JIS適当に多め)
                    if (0xeb00 <= code && code < 0xef00) {
                        sbRet.append((char)KDDIShiftJIStoUnicode(code));
                    } else {
                        sbRet.append(new String(new byte[] {(byte)ch, (byte)ch2}, "Shift_JIS"));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sbRet.toString();
    }

    private int KDDIShiftJIStoUnicode(int sjis) {
        int diff = 0;

        // "(参考)Eメール送出用JISコードに対応したShift-JISコード" から
        // "KDDI絵文字用Shift-JISコード" に変換
        if (0xeb00 <= sjis && sjis < 0xed00) {
            diff = 0xb00;
        } else if (0xed00 <= sjis && sjis < 0xef00) {
            diff = 0x600;
        }
        sjis += diff;

        // "KDDI絵文字用Shift-JISコード" から
        // "Unicode" に変換
        if (sjis >= 0xf340 && sjis <= 0xf352) {
            // 358-376番
            diff = 921;

        } else if (sjis >= 0xf353 && sjis <= 0xf3ce) {
            // 377-499番台
            diff = 2105;

        } else if (sjis >= 0xf3cf && sjis <= 0xf48d) {
            // 700番台以降
            diff = 2124;

        } else if (sjis >= 0xf640 && sjis <= 0xf7d1) {
            // 1-333番
            diff = 0;

        } else if (sjis >= 0xf7d2 && sjis <= 0xf7e4) {
            // 500番台
            diff = 1350;

        } else if (sjis >= 0xf7e5 && sjis <= 0xf7fc) {
            // 334-357番台
            diff = -19;

        } else {
            return 0;
        }

        int high = sjis >> 8;
        int low = sjis & 0xff;
        if (low < 0x80) {
            return 0xe000 + (188 * (high - 0xf0)) + low - 0x40 + diff;
        } else {
            return 0xe000 + (188 * (high - 0xf0)) + low - 0x41 + diff;
        }
    }
}

JISConverter.java

package com.example.android.AuoneMailDemo;

/**
 * JIS操作クラス
 * MyEncode.m 参照
 * 元ネタ(http://7ujm.net/C++/JIStoSJIS.html)
 * @author tsato
 */
public class JISConverter {
    /**
     * JISをSJIS変換して返す。
     * @param byteJis
     * @return
     */
    public static StringBuffer toSJIS(byte[] byteJis) {
        StringBuffer sbRet = new StringBuffer();
        int i = 0;
        int length = byteJis.length;
        Boolean conFlag = false;
        while (i < length) {
            if (byteJis[i] == 0x1B) {
                if ((length-i) >= 3) {
                    if (byteJis[i+1] == 0x24 && byteJis[i+2] == 0x42) {
                        // 2バイト文字の開始
                        i = i + 3;
                        conFlag = true;
                    } else if (byteJis[i+1] == 0x28 && byteJis[i+2] == 0x42) {
                        // ASCII文字の開始
                        i = i + 3;
                        conFlag = false;
                    }
                }
            }
            if (i < length) {
                if(conFlag) {
                    // 2バイト文字の変換
                    char[] cbuf;
                    cbuf = jis2sjis(byteJis, i);
                    sbRet.append(cbuf);
                    i = i + 2;
                } else {
                    // 2バイト文字以外はそのままコピー
                    sbRet.append((char)byteJis[i]);
                    i++;
                }
            }
        }
        return sbRet;
    }
    /**
     * JISコードをSJISコードに変換する。
     * @param ch
     * @param index
     * @return
     */
    private static char[] jis2sjis(byte[] ch, int index) {
        char[] obuf = new char[2];
        char cIn1= (char)ch[index];
        char cIn2= (char)ch[index + 1];
        char c = (char)(cIn1 - 0x21);
        char cOut1 = 0;
        char cOut2 = 0;
        if ((c & 1) == 1) {
            cOut2 = (char)(cIn2 + 0x7e);
        } else {
            cOut2 = (char)(cIn2 + 0x1f);
            if (0x7f <= cOut2 && cOut2 <= 0x9d) {
                cOut2++;
            }
        }
        cOut1 = (char)(c >> 1);
        if (cOut1 <= 0x1e){
            cOut1 += 0x81;
        } else {
            cOut1 += 0xc1;
        }
        obuf[0] = cOut1;
        obuf[1] = cOut2;
        return obuf;
    }
}