プッシュメールの受信
au-one(gmail)からのプッシュメールの通知を受け取れるようになった。
IMAPFolderのidle()で取れるみたい。
idle()でメールが来るまで待機しているのでスレッドにする。
指定フォルダ(INBOX)に変化があれば通知される。
idleコマンドのサーバー側タイムアウトとかで再接続されるとか確認できていない。
IMAP4プロトコルのIDLEコマンドを使う。
参考サイト
GmailAssistant
http://gmailassistant.sourceforge.net/
package com.example.android.IMAPDemo; import java.util.ArrayList; import java.util.List; import java.util.Properties; import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Store; import javax.mail.event.MessageCountEvent; import javax.mail.event.MessageCountListener; import javax.mail.internet.InternetAddress; import com.sun.mail.imap.IMAPFolder; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class IMAPDemoActivity extends Activity { private Button buttonStart; private Button buttonStop; private TextView textMessage; private Handler mHandler = new Handler(); private List mListLog = new ArrayList(); private boolean mIdleStop = false; private Thread mThread = null; private Store mStore = null; private IMAPFolder mFolder = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); buttonStart = (Button)findViewById(R.id.buttonStart); buttonStart.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { buttonStart_onClick(); } }); buttonStop = (Button)findViewById(R.id.buttonStop); buttonStop.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { buttonStop_onClick(); } }); textMessage = (TextView)findViewById(R.id.textMessage); Bundle bundle = textMessage.getInputExtras(true); bundle.putBoolean("allowEmoji", true); } @Override protected void onPause () { super.onPause(); } public void buttonStart_onClick() { 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"); //Properties props = System.getProperties(); Session sess = Session.getDefaultInstance(props, null); String user = "*****@auone.jp"; String password = "*****"; String push_folder = "INBOX"; try { mStore = sess.getStore("imaps"); mStore.connect("imap.gmail.com", 993, user, password); // メール通知確認を開始 startIdleLoop(mStore, push_folder); } catch (Exception e) { e.printStackTrace(); } } public void buttonStop_onClick() { mIdleStop = true; if (mFolder != null) { try { mFolder.close(false); } catch (Exception e) { e.printStackTrace(); } } if (mStore != null) { try { mStore.close(); } catch (Exception e) { e.printStackTrace(); } } // メール通知確認を停止 stopIdleLoop(); } /** * メール通知確認を開始 * @param mailStore * @param mailFolder */ private void startIdleLoop(final Store mailStore, final String mailFolder) { Runnable runner = new Runnable() { public void run() { //INBOXに変化があった final MessageCountListener idleListener = new MessageCountListener() { //メールが追加(別フォルダから移動でも) public void messagesAdded(MessageCountEvent e) { String subject = ""; try { Message message[] = e.getMessages(); statusCall(message[0]); subject = message[0].getSubject(); } catch (MessagingException me) { me.printStackTrace(); subject = me.toString(); } setMessage("Added: " + subject); } //メールが削除(別フォルダに移動でも) public void messagesRemoved(MessageCountEvent e) { setMessage("Removed"); } }; NextIdleIteration: while (!mIdleStop) { sleep(2000L); try { mFolder = (IMAPFolder)mailStore.getFolder(mailFolder); mFolder.addMessageCountListener(idleListener); if (!mFolder.exists()) { continue NextIdleIteration; } if (!mFolder.isOpen()) { mFolder.open(Folder.READ_ONLY); } setMessage("idle called"); // idle() でメールが来るまで待機してる // メールが来ると抜ける mFolder.idle(); setMessage("idle returned"); } catch (Exception e) { e.printStackTrace(); } } } }; mThread = new Thread(runner); mThread.start(); } /** * メール通知確認を停止 */ private void stopIdleLoop() { mIdleStop = true; if (mThread != null) { mThread.interrupt(); } } private void statusCall(final Message message) { mHandler.post(new Runnable() { @Override public void run() { try { InternetAddress addrFrom = (InternetAddress)message.getFrom()[0]; String address = addrFrom.getAddress(); String subject = message.getSubject(); NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); Notification notification = new Notification( R.drawable.icon, "メールが届きました", System.currentTimeMillis()); Intent intent = new Intent(Intent.ACTION_VIEW); PendingIntent contentIntent = PendingIntent.getActivity(IMAPDemoActivity.this, 0, intent, 0); notification.setLatestEventInfo( IMAPDemoActivity.this, address, subject, contentIntent); notificationManager.notify(R.string.app_name, notification); } catch (MessagingException e) { e.printStackTrace(); } } }); } private void setMessage(final String log) { mHandler.post(new Runnable() { @Override public void run() { if (mListLog.size() > 20) { mListLog.remove(0); } mListLog.add(log + "\n"); StringBuffer sb = new StringBuffer(); for (int i = 0; i < mListLog.size(); i++) { sb.append(mListLog.get(i)); } textMessage.setText(sb.toString()); } }); } private void sleep(long millis) { try { Thread.sleep(millis); } catch (Exception e) { e.printStackTrace(); } } }