短信拦截的二种处理方式
程序员文章站
2022-05-20 20:49:03
...
最近项目中要做的一个拦截某一个特定号码发来的短信的小功能,遇到到小问题(不得不说有些软件好过分啊),记录一下。
1:拦截系统发送的短信广播
我们知道,系统在收到短信的时候,会发送一个短信广播,而广播的种类又分为有序广播和无序广播,而这个短信广播就是有序广播,我们在收到这个广播之后,可以abort掉,那么优先级在你后面的receiver就会接收不到这个广播了,然后麻烦就来了,有些短信软件比如说youni,360等等就会abort掉后让你接受不到这个广播了,还有一些定制android的rom根本不会让你接收到这个广播,也就是说通过广播来做拦截是有前提的。
2:通过ContentObserver监听短信数据库
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";