Android開發之監聽或獲取手機短信內容



最近做的項目裏要監聽手機的短消息內容,這個東西好像在最初學的時候都做過,不過現在早忘記了,現在寫下來,記住了。



前提--權限:

    <uses-permission android:name="android.permission.RECEIVE_SMS" >
    </uses-permission>
    <uses-permission android:name="android.permission.READ_SMS" >
    </uses-permission>


方式一:通過廣播監聽短信消息

(注意:這種方式只對新收到的短消息有效,運行代碼,並不會讀取收件箱中已讀或未讀的消息,只有當收到新來的短消息時,纔會執行onChange方法)


註冊一個廣播:

 <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

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

}


系統的這個廣播是有序廣播,就是當別的程序先獲取到了這個廣播再傳遞給你,當然它也可以幹掉這個廣播,讓你接收不到,這樣你的程序肯定是接收不到這個廣播的了。我們發現,通過設置priority的數值,其實有時是不管用的,現在在一些定製的系統或是有安全軟件的情況下,往往短消息都被截取到,並被幹掉。

那麼,我們只能使用方法二,監聽短信數據庫的變化,這種方式比方法一稍微複雜一些,不過使用起來也很方便,不受其它程序干擾~


方式二:通過短信數據庫獲取短信內容

(注意:這種方式可以獲取手機上所有的短信,包括已讀未讀的短信,是不是很贊)

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"));//聯繫人姓名列表
			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主要結構:
  
  _id:短信序號,如100
  
  thread_id:對話的序號,如100,與同一個手機號互發的短信,其序號是相同的
  
  address:發件人地址,即手機號,如+86138138000
  
  person:發件人,如果發件人在通訊錄中則爲具體姓名,陌生人爲null
  
  date:日期,long型,如1346988516,可以對日期顯示格式進行設置
  
  protocol:協議0SMS_RPOTO短信,1MMS_PROTO彩信
  
  read:是否閱讀0未讀,1已讀
  
  status:短信狀態-1接收,0complete,64pending,128failed
  
  type:短信類型1是接收到的,2是已發出
  
  body:短信具體內容
  
  service_center:短信服務中心號碼編號,如+8613800755500


通過方式二,我們就能獲取手機中所有的短消息了,可是還有一個問題,如果來了新的短消息呢?我們總不能寫個線程,每隔多少秒,去讀取一下短信數據庫吧?其實我們可以把方式二換個方式寫:

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() {
		//這裏可以進行回調的操作
		//TODO

	};
	class SmsObserver extends ContentObserver {

		public SmsObserver(Context context, Handler handler) {
			super(handler);
		}

		@Override
		public void onChange(boolean selfChange) {
			super.onChange(selfChange);
			//每當有新短信到來時,使用我們獲取短消息的方法
			getSmsFromPhone();
		}
	}



效果:



發佈了95 篇原創文章 · 獲贊 123 · 訪問量 486萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章