Android监听手机短信 Android监听手机短信的代码实例
Crocutax''''s Blog 人气:0想了解Android监听手机短信的代码实例的相关内容吗,Crocutax''''s Blog在本文为您仔细讲解Android监听手机短信的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:Android监听手机短信,Android监听短信,下面大家一起来学习吧。
本文介绍了Android监听手机短信的示例代码,分享给大家,具体如下:
以下情况可能会导致短信拦截失败:
- 小米,360等品牌手机拦截短信,短信的优先级给了系统
- 用户禁用短信权限
- 手机连接电脑,被电脑端的手机助手类软件截获
- 手机内装有QQ通讯录之类的管理联系人,短信的应用,被截获.
前提--权限:
<uses-permission android:name="android.permission.RECEIVE_SMS" > </uses-permission> <uses-permission android:name="android.permission.READ_SMS" > </uses-permission>
定义短信广播接收者
public class SMSBroadcastReceiverextends BroadcastReceiver{ private static OnReceivedMessageListener mOnReceivedMessageListener; public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED"; public SMSBroadcastReceiver(){ super(); } @Override public void onReceive(Context context, Intent intent){ if (intent.getAction().equals(SMS_RECEIVED_ACTION)) { Object[] pdus = (Object[]) intent.getExtras().get("pdus"); for(Object pdu:pdus) { SmsMessage smsMessage = SmsMessage.createFromPdu((byte [])pdu); String sender = smsMessage.getDisplayOriginatingAddress(); String content = smsMessage.getDisplayMessageBody(); long date = smsMessage.getTimestampMillis(); Date tiemDate = new Date(date); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String time = simpleDateFormat.format(tiemDate); //过滤不需要读取的短信的发送号码 if ("106902780116481".equals(sender)) { mOnReceivedMessageListener.onReceived(getDynamicPassword(content)); abortBroadcast(); } } } } public interface OnReceivedMessageListener{ void onReceived(String message); } public void setOnReceivedMessageListener(OnReceivedMessageListener onReceivedMessageListener){ this.mOnReceivedMessageListener = onReceivedMessageListener; } /** * 从字符串中截取连续6位数字组合 ([0-9]{" + 6 + "})截取六位数字 进行前后断言不能出现数字 用于从短信中获取动态密码 * @param str 短信内容 * @return 截取得到的6位动态密码 */ public String getDynamicPassword(String str){ // 6是验证码的位数,一般为六位 Pattern continuousNumberPattern = Pattern.compile("(?<![0-9])([0-9]{" + 6 + "})(?![0-9])"); Matcher m = continuousNumberPattern.matcher(str); String dynamicPassword = ""; while (m.find()) { dynamicPassword = m.group(); } return dynamicPassword; } }
注册广播
SMSBroadcastReceiver = mSMSBroadcastReceiver = new SMSBroadcastReceiver(); IntentFilter intentFilter = new IntentFilter(SMSBroadcastReceiver.SMS_RECEIVED_ACTION); intentFilter.setPriority(Integer.MAX_VALUE); this.registerReceiver(mSMSBroadcastReceiver, intentFilter); ToastManager.getInstance().showLongToast("注册短信监听"); mSMSBroadcastReceiver.setOnReceivedMessageListener(new SMSBroadcastReceiver.OnReceivedMessageListener() { @Override public void onReceived(String message){ //do something } });
方式二:监听短信数据库
内容提供者中对外通信方式有3种:
方式1:定义为Activity的内部类,直接在onChang()方法中处理业务逻辑,比如收到短信之后设置给EditText
- 优点:方便
- 缺点:耦合度高,复用性差
方式2:定义接口,Activity实现这个接口,拿到回调,处理业务逻辑
- 优点:耦合度低,复用性高
- 缺点没用充分利用Handler资源
代码如下:
/** * Created by wxw on 2016/9/24 10:34 * function: 监听短信数据库 * e-mail:wangxw725@163.com */ public class SmsContentObserverextends ContentObserver{ private Cursor cursor = null; private Context mContext; private String[] projection = new String[]{"_id","body"}; private OnMessageObservedListener mOnMessageObservedListener; public SmsContentObserver(Context context,Handler handler){ super(handler); this.mContext = context; } public interface OnMessageObservedListener{ void onObservedMessage(String message); } public void setOnMessageObservedListener(OnMessageObservedListener onMessageObservedListener){ this.mOnMessageObservedListener = onMessageObservedListener; } @Override public void onChange(boolean selfChange){ super.onChange(selfChange); cursor = mContext.getContentResolver().query(Uri.parse("content://sms/inbox"), projection,null, null, "_id desc"); if (cursor != null && cursor.getCount() > 0) { cursor.moveToNext(); int smsbodyColumn = cursor.getColumnIndex("body"); String smsBody = cursor.getString(smsbodyColumn); mOnMessageObservedListener.onObservedMessage(getDynamicPassword(smsBody)); } cursor.close(); } private String getDynamicPassword(String str){ Pattern continuousNumberPattern = Pattern.compile("(?<![0-9])([0-9]{" + 6 + "})(?![0-9])"); Matcher m = continuousNumberPattern.matcher(str); String dynamicPassword = ""; while (m.find()) { dynamicPassword = m.group(); } return dynamicPassword; } }
方式3:通过Handler发送消息,在Activity中进行业务逻辑处理
代码如下:
/** * Created by wxw on 2016/9/24 10:34 * function: 监听短信数据库 * e-mail:wangxw725@163.com */ public class SmsContentObserverextends ContentObserver{ private Cursor cursor = null; private Context mContext; private Handler mHandler; private String[] projection = new String[]{"_id","body"}; public SmsContentObserver(Context context,Handler handler){ super(handler); this.mContext = context; this.mHandler = handler; } @Override public void onChange(boolean selfChange){ super.onChange(selfChange); cursor = mContext.getContentResolver().query(Uri.parse("content://sms/inbox"), projection,null, null, "_id desc"); if (cursor != null && cursor.getCount() > 0) { cursor.moveToNext(); int smsbodyColumn = cursor.getColumnIndex("body"); String smsBody = cursor.getString(smsbodyColumn); mHandler.obtainMessage(1,getDynamicPassword(smsBody)).sendToTarget(); } cursor.close(); } private String getDynamicPassword(String str){ Pattern continuousNumberPattern = Pattern.compile("(?<![0-9])([0-9]{" + 6 + "})(?![0-9])"); Matcher m = continuousNumberPattern.matcher(str); String dynamicPassword = ""; while (m.find()) { dynamicPassword = m.group(); } return dynamicPassword; } }
注册观察者
smsContentObserver = new SmsContentObserver(this, smsHandler); getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, smsContentObserver);
handler中处理消息
private Handler smsHandler = new Handler(){ @Override public void handleMessage(Message msg){ switch (msg.what){ case 0: ...... break; case 1: LogUtils.x("Activity收到了短息码:"+(String)msg.obj); lf.mEtPassword.setText((String)msg.obj); break; } } };
注销观察者
@Override protected void onDestroy(){ super.onDestroy(); ...... if(smsContentObserver!=null){ getContentResolver().unregisterContentObserver(smsContentObserver); smsContentObserver = null; } }
遗留问题
观察者会多次回调onChang方法()
加载全部内容