http://blog.csdn.net/mad1989/article/details/22426415
最近做的項目里要監(jiān)聽手機的短消息內(nèi)容,這個東西好像在最初學的時候都做過,不過現(xiàn)在早忘記了,現(xiàn)在寫下來,記住了。
前提--權限:
[java] view plaincopy
- <uses-permission android:name="android.permission.RECEIVE_SMS" >
- </uses-permission>
- <uses-permission android:name="android.permission.READ_SMS" >
- </uses-permission>
方式一:通過廣播監(jiān)聽短信消息
(注意:這種方式只對新收到的短消息有效,運行代碼,并不會讀取收件箱中已讀或未讀的消息,只有當收到新來的短消息時,才會執(zhí)行onChange方法)
注冊一個廣播:
[java] view plaincopy
- <receiver android:name="com.dbjtech.acbxt.waiqin.SmsReciver" >
- <intent-filter android:priority="999">
- <action android:name="android.provider.Telephony.SMS_RECEIVED" />
- </intent-filter>
- </receiver>
SmsReceiver.java
[java] view plaincopy
- public class SmsReciver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- Bundle bundle = intent.getExtras();
- SmsMessage msg = null;
- if (null != bundle) {
- Object[] smsObj = (Object[]) bundle.get("pdus");
- for (Object object : smsObj) {
- msg = SmsMessage.createFromPdu((byte[]) object);
- Date date = new Date(msg.getTimestampMillis());//時間
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- String receiveTime = format.format(date);
- System.out.println("number:" + msg.getOriginatingAddress()
- + " body:" + msg.getDisplayMessageBody() + " time:"
- + msg.getTimestampMillis());
-
- //在這里寫自己的邏輯
- if (msg.getOriginatingAddress().equals("10086")) {
- //TODO
-
- }
-
- }
- }
- }
-
- }
系統(tǒng)的這個廣播是有序廣播,就是當別的程序先獲取到了這個廣播再傳遞給你,當然它也可以干掉這個廣播,讓你接收不到,這樣你的程序肯定是接收不到這個廣播的了。我們發(fā)現(xiàn),通過設置priority的數(shù)值,其實有時是不管用的,現(xiàn)在在一些定制的系統(tǒng)或是有安全軟件的情況下,往往短消息都被截取到,并被干掉。
那么,我們只能使用方法二,監(jiān)聽短信數(shù)據(jù)庫的變化,這種方式比方法一稍微復雜一些,不過使用起來也很方便,不受其它程序干擾~
方式二:通過短信數(shù)據(jù)庫獲取短信內(nèi)容
(注意:這種方式可以獲取手機上所有的短信,包括已讀未讀的短信,是不是很贊)
[java] view plaincopy
- private Uri SMS_INBOX = Uri.parse("content://sms/");
- public void getSmsFromPhone() {
- ContentResolver cr = getContentResolver();
- String[] projection = new String[] { "body" };//"_id", "address", "person",, "date", "type
- String where = " address = '1066321332' AND date > "
- + (System.currentTimeMillis() - 10 * 60 * 1000);
- Cursor cur = cr.query(SMS_INBOX, projection, where, null, "date desc");
- if (null == cur)
- return;
- if (cur.moveToNext()) {
- String number = cur.getString(cur.getColumnIndex("address"));//手機號
- String name = cur.getString(cur.getColumnIndex("person"));//聯(lián)系人姓名列表
- String body = cur.getString(cur.getColumnIndex("body"));
- //這里我是要獲取自己短信服務號碼中的驗證碼~~
- Pattern pattern = Pattern.compile(" [a-zA-Z0-9]{10}");
- Matcher matcher = pattern.matcher(body);
- if (matcher.find()) {
- String res = matcher.group().substring(1, 11);
- mobileText.setText(res);
- }
- }
- }
sms主要結(jié)構:
_id:短信序號,如100
thread_id:對話的序號,如100,與同一個手機號互發(fā)的短信,其序號是相同的
address:發(fā)件人地址,即手機號,如+86138138000
person:發(fā)件人,如果發(fā)件人在通訊錄中則為具體姓名,陌生人為null
date:日期,long型,如1346988516,可以對日期顯示格式進行設置
protocol:協(xié)議0SMS_RPOTO短信,1MMS_PROTO彩信
read:是否閱讀0未讀,1已讀
status:短信狀態(tài)-1接收,0complete,64pending,128failed
type:短信類型1是接收到的,2是已發(fā)出
body:短信具體內(nèi)容
service_center:短信服務中心號碼編號,如+8613800755500
通過方式二,我們就能獲取手機中所有的短消息了,可是還有一個問題,如果來了新的短消息呢?我們總不能寫個線程,每隔多少秒,去讀取一下短信數(shù)據(jù)庫吧?其實我們可以把方式二換個方式寫:
[java] view plaincopy
- private SmsObserver smsObserver;
-
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.app_login);
- smsObserver = new SmsObserver(this, smsHandler);
- getContentResolver().registerContentObserver(SMS_INBOX, true,
- smsObserver);
-
- }
- public Handler smsHandler = new Handler() {
- //這里可以進行回調(diào)的操作
- //TODO
-
- };
- class SmsObserver extends ContentObserver {
-
- public SmsObserver(Context context, Handler handler) {
- super(handler);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- super.onChange(selfChange);
- //每當有新短信到來時,使用我們獲取短消息的方法
- getSmsFromPhone();
- }
- }
效果:
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請
點擊舉報。