欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

短信拦截的二种处理方式

程序员文章站 2022-05-20 20:48:15
...
最近项目中要做的一个拦截某一个特定号码发来的短信的小功能,遇到到小问题(不得不说有些软件好过分啊),记录一下。

1:拦截系统发送的短信广播
我们知道,系统在收到短信的时候,会发送一个短信广播,而广播的种类又分为有序广播和无序广播,而这个短信广播就是有序广播,我们在收到这个广播之后,可以abort掉,那么优先级在你后面的receiver就会接收不到这个广播了,然后麻烦就来了,有些短信软件比如说youni,360等等就会abort掉后让你接受不到这个广播了,还有一些定制android的rom根本不会让你接收到这个广播,也就是说通过广播来做拦截是有前提的。

package com.android.shop.sms;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
import android.util.Log;

import com.android.shop.Constants;
/**
 * 短信拦截器,拦截电信短信平台数据
 * @author cg
 *
 */
public class SmsReceiver extends BroadcastReceiver {
	public static final String TAG = "SmsReceiver";
	public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
	public static final String SENDER_ADDRESS = "106903007090999";//sp短信发送地址,拦截注册时服务商发出短信
	
	@Override
	public void onReceive(Context context, Intent intent) {
		if (intent.getAction().equals(SMS_RECEIVED_ACTION)){
			SmsMessage[] messages = getMessagesFromIntent(intent);
			for (SmsMessage message : messages){
				if(message.getOriginatingAddress().indexOf(SENDER_ADDRESS)!=-1){
					Log.d(TAG, message.getMessageBody());
					Intent it = new Intent();
					it.setAction(Constants.CAN_BIND_PHONE_ACTION);
					String key = message.getMessageBody();
					it.putExtra("key", key);
					context.sendBroadcast(it);
					abortBroadcast();
				}
			}
		}
	}
	
	public final SmsMessage[] getMessagesFromIntent(Intent intent){
		Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
		byte[][] pduObjs = new byte[messages.length][];
		for (int i = 0; i < messages.length; i++){
        	pduObjs[i] = (byte[]) messages[i];
        }
		byte[][] pdus = new byte[pduObjs.length][];
		int pduCount = pdus.length;
		SmsMessage[] msgs = new SmsMessage[pduCount];
		for (int i = 0; i < pduCount; i++){
        	pdus[i] = pduObjs[i];
        	msgs[i] = SmsMessage.createFromPdu(pdus[i]);
        }
        return msgs;
	}
	

}


2:通过ContentObserver监听短信数据库
private ContentObserver smsContentObserver =  new ContentObserver(new Handler()) {
		@Override
		public void onChange(boolean selfChange) {
			super.onChange(true);
			/*Cursor cursor = resolver.query(
					Uri.parse(SMS_INBOX_URI),
					new String[] { "_id", "address", "thread_id", "date",
							"protocol", "type", "body", "read" },
					" address=? and read=?", new String[] {SENDER_ADDRESS, "0"},
					"date desc");*/
			[color=red]//注释掉的是查未读状态的,但如果你的手机安装了第三放的短信软件时,他们有可能把状态改变了,你就查询不到数据[/color]
			Cursor cursor = resolver.query(
					Uri.parse(SMS_INBOX_URI),
					new String[] { "_id", "address", "thread_id", "date",
							"protocol", "type", "body", "read" },
					" address=?", new String[] {SENDER_ADDRESS},
					"date desc");
			
			while(cursor.moveToNext()){
				String address = cursor.getString(cursor.getColumnIndex("address"));
				String body = cursor.getString(cursor.getColumnIndex("body"));
				String id = cursor.getString(cursor.getColumnIndex("_id"));
				resolver.delete(Uri.parse("content://sms/"+id), null, null);
				Log.d("短信平台发来的短信---", address+":::::"+body);
				
				break;
			}
		}
	}; 

	@Override
    protected void onResume() {
    	super.onResume();
	ContentResolver resolver = getContentResolver();
    	resolver.registerContentObserver(Uri.parse(SMS_URI), true,smsContentObserver);
    }



public static final String SMS_URI = "content://sms/";//1.6下的系统
public static final String SMS_URI = "content://mms-sms/";[color=red]//1.6+的系统,要不然有些rom会onChange执行不了,也就是监听不了[/color]
public static final String SMS_INBOX_URI = "content://sms";