Cメール(SMS)を通知に使ってEメールを受信する
前の携帯(ガラケー?)から、Eメールの転送設定で、~@auone.jpとCメールに転送させる。
CメールのアドレスはGoogleで「Cメール 転送」あたりで調べて下さい。
***********.fs@kct.dion.ne.jp (関西地方)で登録した。
(".fs"はfromとsubjectのみを転送の意味)
以下の内容のCメールが届いた
Fr:*****@ezweb.ne.jp\n Sub:テストメール
メリット
・IMAP IDLEでずっと待たなくて良いから電池の持ちが良いかもしれない。
デメリット
・転送設定が面倒(最初だけ)
・9月下旬になったら必要ない。
サービスにしたり、ソースを整理したり、やることがいっぱいですがとりあえず動くソースを載せます。
Android用のJavaMailが必要です。(ファイル3つ)
プログラムの参考元
SMSの受信
http://meloncake.sblo.jp/article/41242112.html
SMSの削除、ブロードキャストの通知抑制
http://stackoverflow.com/questions/419184/how-to-delete-an-sms-from-the-inbox-in-android-programmatically
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.SMSMailDemo" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="10" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"> <activity android:name=".SMSMailDemoActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".SMSReceiver"> <intent-filter android:priority="100"> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> <intent-filter> <action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" /> <data android:mimeType="*/*" /> </intent-filter> </receiver> </application> </manifest>
"android.provider.Telephony.SMS_RECEIVED"が必要。
<intent-filter android:priority="100">とすることで、ブロードキャストを受信する優先度を上げれるみたい。
上げてどうするのか?一番最初にSMS_RECEIVEDを受け取って、それ以降に流さないようにして通常のCメールアプリにSMSが届かないようにする。
"android.provider.Telephony.WAP_PUSH_RECEIVED"は使ってないので削除可能。
SMSMailDemoActivity.java
package com.example.android.SMSMailDemo; import java.util.Properties; import javax.mail.Folder; import javax.mail.Message; import javax.mail.Session; import javax.mail.Store; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import android.app.Activity; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.telephony.SmsMessage; import android.widget.TextView; public class SMSMailDemoActivity extends Activity { private static SMSMailDemoActivity me; private static TextView messageView; private static String mUser = "*****@auone.jp"; private static String mPassword = "*****"; private static String mTargetFolder = "INBOX"; public SMSMailDemoActivity() { me = this; } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); messageView = (TextView)findViewById(R.id.messageView); Bundle bundle = messageView.getInputExtras(true); bundle.putBoolean("allowEmoji", true); } public static Handler hander = new Handler() { @Override public void handleMessage(android.os.Message msg) { try { SmsMessage smsMsg = (SmsMessage)msg.obj; String body[] = smsMsg.getMessageBody().split("\n"); // Fr: を抜き出し InternetAddress addrFrom = new InternetAddress(body[0].substring(3)); // Sub: を抜き出し String sub = body[1].substring(4); // //InternetAddress addrFrom = new InternetAddress(msg.getData().get("from").toString()); //String sub = msg.getData().get("sub").toString(); viewSubject(addrFrom, sub); // // 受信したSMSを削除する(エラーで失敗したので要確認) /* Uri deleteUri = Uri.parse("content://sms"); me.getContentResolver().delete( deleteUri, "address=? and date=?", new String[] { smsMsg.getOriginatingAddress(), String.valueOf(smsMsg.getTimestampMillis()) }); */ } catch (AddressException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } } }; private static void viewSubject(InternetAddress cmAddress, String cmSubject) { Properties props = new Properties(); props.setProperty("mail.store.protocol", "imaps"); 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 totalMsg = folder.getMessageCount(); //INBOXの全件数 int unreadMsg = folder.getUnreadMessageCount(); //未読数 //未読数分だけ取得する(最初のほうに未読が残っていれば意味ない) Message[] messages = folder.getMessages(totalMsg - unreadMsg, totalMsg); StringBuffer sb = new StringBuffer(); String text = "見つかりませんでした。"; for (int i = unreadMsg; i > 0; i--) { Message message = messages[i]; if (message.isMimeType("text/plain")) { InternetAddress[] addrFrom = (InternetAddress[])message.getFrom(); // Cメールで受信したFromと、Eメールで受信したFromが一緒なら表示して抜ける // Subjectも一緒じゃないとダメ!なのが抜けてる if (addrFrom[0].getAddress().equals(cmAddress.getAddress())) { text = String.format("%s\n%s\n", addrFrom[0].getAddress(), message.getSubject()); sb.append(text); sb.append(getBody(message)); break; } } } messageView.setText(sb.toString()); // フォルダーを閉じます folder.close(false); } catch (Exception e) { e.printStackTrace(); } finally { try { if (store != null) { store.close(); } } catch (Exception e) { e.printStackTrace(); } } } // 絵文字の対応とかをする private static String getBody(Message message) { String body = null; try { body = message.getContent().toString(); } catch (Exception e) { e.printStackTrace(); } return body; } }
SMSReceiver.java
package com.example.android.SMSMailDemo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Message; import android.telephony.SmsMessage; import android.util.Log; public class SMSReceiver extends BroadcastReceiver { private static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED"; private static final String WAP_PUSH_RECEIVED_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED"; private static final String TAG = "SMSReceiver"; @Override public void onReceive(Context cntxt, Intent intent) { // 電話番号でのSMSはこっちで届いた // EメールのCメールへの転送設定は、こっちで届いた if (SMS_RECEIVED_ACTION.equals(intent.getAction())) { Bundle extras = intent.getExtras(); if (extras != null) { /* SMS_RECEIVED の受信優先度を上げて(1~100) abortBroadcast() で以降ブロードキャストをとめる * <intent-filter android:priority="100"> * <action android:name="android.provider.Telephony.SMS_RECEIVED" /> * </intent-filter> */ abortBroadcast(); Log.d(TAG, "SMS_RECEIVED"); // pduのデコードとログ出力 // サンプルのためBroadcastReceiverで処理(本来はServiceで) Object[] pdus = (Object[])extras.get("pdus"); for (Object pdu: pdus) { SmsMessage smsMessage = SmsMessage.createFromPdu((byte[])pdu); Log.d(TAG, "from:" + smsMessage.getOriginatingAddress()); Log.d(TAG, "time:" + Long.toString(smsMessage.getTimestampMillis())); Log.d(TAG, "body:" + smsMessage.getMessageBody().replaceAll("\n", "\t")); //reciveSms(smsMessage.getMessageBody()); reciveSms(smsMessage); } } // 使ってない、いつ届くか未確認 } else if (WAP_PUSH_RECEIVED_ACTION.equals(intent.getAction())) { Bundle extras = intent.getExtras(); if (extras != null) { Log.d(TAG, "WAP_PUSH_RECEIVED"); int transactionId = extras.getInt("transactionId"); int pduType = extras.getInt("pduType"); byte[] header = extras.getByteArray("header"); byte[] data = extras.getByteArray("data"); Log.d(TAG, "contentType: " + ((intent.getType() != null) ? intent.getType() : "")); Log.d(TAG, "transactionId: " + Integer.toString(transactionId)); Log.d(TAG, "pduType: " + Integer.toString(pduType)); if (header != null) { for (int i = 0; i < header.length; i++) { Log.d(TAG, String.format("header[%03d]: 0x%02x (%s)", i, header[i], (char)header[i])); } } else { Log.d(TAG, "header is null"); } if (data != null) { for (int i = 0; i < data.length; i++) { Log.d(TAG, String.format("data[%03d]: 0x%02x (%s)", i, data[i], (char)data[i])); } } else { Log.d(TAG, "data is null"); } } } } //Fr:*****@ezweb.ne.jp\n //Sub:テストメール private void reciveSms(String smsMessage) { Message msg = new Message(); Bundle bundle = new Bundle(); String[] message = smsMessage.split("\n"); bundle.putString("from", message[0].substring(3)); bundle.putString("sub", message[1].substring(4)); msg.setData(bundle); SMSMailDemoActivity.hander.sendMessage(msg); } private void reciveSms(SmsMessage smsMessage) { Message msg = new Message(); msg.obj = smsMessage; SMSMailDemoActivity.hander.sendMessage(msg); } }
IS11Sには、デフォルトでCメールアプリがあるので、そっちにも通知が行く。
それをなくす為に、SMSを削除しようとしたけど出来なかった(要確認)。
結局、ブロードキャストの通知を1番最初に取得して消して、以降に流さないようにした。
あと、Handerの使い方がよく分からなかった。