au-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; } }