观察者模式:

观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

观察者模式提供了一种对象设计, 让主题和观察者之间松耦合。主题只知道观察者实现了某个接口(也就是Observer接口)。主题不需要知道观察者的具体类是谁、做了些什么或其他任何细节。任何时候我们都可以增加新的观察者。因为主题唯一依赖的东西是一个实现Observer接口的对象列表,所以我们可以随时增加观察者。同样我们也可以删除观察者。有新类型的观察者出现时,主题的代码不需要修改。它只会发送通知给所有实现了观察者接口的对象。

项目的Gihub地址:

https://github.com/Robin-jiangyufeng/SmsObserverForAndroid

这是一个用于拦截android实时短信的库,可以进行短信过滤,得到自己想要的内容,可以用于需要自动填写短信验证码的app项目。

该项目可以用于监听当前接收到的短信信息,并过滤接收到的短信,得到自己想要的内容,还可以用于发送短信验证码。

首先看一下程序使用的基类:

https://github.com/Robin-jiangyufeng/SmsObserverForAndroid/tree/master/SmsObserverLibrary/src/main/java/com/robin/lazy/sms

这个目录下有几个基类:

SmsFilter.java是一个过滤器接口,定义了一个过滤的抽象方法filter()。

public interface SmsFilter {

    /***
* 过滤方法
* @param address 发信人
* @param smsContent 短信内容
* @return 过滤处理后的短信信息
*/
String filter(String address,String smsContent);
}

DefaultSmsFilter.java是一个SmsFilter接口的具体实现子类,实现了filter方法()。

public class DefaultSmsFilter implements SmsFilter{

    @Override
public String filter(String address, String smsContent) {
return smsContent;
}
}

SmsHandler是一个Handler的子类,类内部定义了两个构造方法SmsHandler(),然后定义了一个设置过滤器的方法setSmsFilter(),最后覆写了父类Handler的handleMessage()方法,目的是加入自己写的过滤器来有选择地处理信息。

public class SmsHandler extends Handler {

    private SmsResponseCallback mCallback;

    /***
* 短信过滤器
*/
private SmsFilter smsFilter; public SmsHandler(SmsResponseCallback callback) {
this.mCallback = callback;
} public SmsHandler(SmsResponseCallback callback, SmsFilter smsFilter) {
this(callback);
this.smsFilter = smsFilter;
} /***
* 设置短信过滤器
* @param smsFilter 短信过滤器
*/
public void setSmsFilter(SmsFilter smsFilter) {
this.smsFilter = smsFilter;
} @Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == SmsObserver.MSG_RECEIVED_CODE) {
String[] smsInfos = (String[]) msg.obj;
if (smsInfos != null && smsInfos.length == 2 && mCallback != null) {
if (smsFilter == null) {
smsFilter = new DefaultSmsFilter();
}
mCallback.onCallbackSmsContent(smsFilter.filter(smsInfos[0], smsInfos[1]));
}
}
}
}

SmsResponseCallback.java类负责发出通知(这里具体来说就是针对过滤器过滤后的短信进行不同的通知,比如合规的短信将进行自动回复,后面主活动中覆写了这个方法)

public interface SmsResponseCallback {

    /**
* 返回短信内容
*
* @param smsContent
* @see [类、类#方法、类#成员]
*/
void onCallbackSmsContent(String smsContent);
}

VerificationCodeSmsFilter.java类是另一个过滤器子类,负责过滤要给哪些人发送短信。

public class VerificationCodeSmsFilter implements SmsFilter {
/**
* 需要过滤的发短信的人
*/
private String filterAddress; public VerificationCodeSmsFilter(String filterAddress) {
this.filterAddress = filterAddress;
} @Override
public String filter(String address, String smsContent) {
if (address.startsWith(filterAddress)) {
Pattern pattern = Pattern.compile("(\\d{4,8})");//匹配4-8位的数字
Matcher matcher = pattern.matcher(smsContent);
if (matcher.find()) {
return matcher.group(0);
}
}
return null;
}
}

SmsObserver.java是一个观察者类,定义了观察者的一系列方法。

https://github.com/Robin-jiangyufeng/SmsObserverForAndroid/blob/master/SmsObserverLibrary/src/main/java/com/robin/lazy/sms/SmsObserver.java

先设置了三个不同的构造方法:

public SmsObserver(Activity context, SmsResponseCallback callback,SmsFilter smsFilter) {
this(new SmsHandler(callback,smsFilter));
this.mContext = context;
} public SmsObserver(Activity context, SmsResponseCallback callback) {
this(new SmsHandler(callback));
this.mContext = context;
} public SmsObserver(SmsHandler handler) {
super(handler);
this.mHandler = handler;
}

设置一个短信过滤的方法:

 public void setSmsFilter(SmsFilter smsFilter) {
mHandler.setSmsFilter(smsFilter);
}

注册一个短信观察者的方法:

public void registerSMSObserver() {
Uri uri = Uri.parse("content://sms");
if (mContext != null) {
mContext.getContentResolver().registerContentObserver(uri,
true, this);
}
}

删除一个短信观察者的方法:

public void unregisterSMSObserver() {
if (mContext != null) {
mContext.getContentResolver().unregisterContentObserver(this);
}
if (mHandler != null) {
mHandler = null;
}
}

设置状态变化并发出通知的方法:

@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if (uri.toString().equals("content://sms/raw")) {
return;
}
Uri inboxUri = Uri.parse("content://sms/inbox");//收件箱
try {
Cursor c = mContext.getContentResolver().query(inboxUri, null, null,
null, "date desc");
if (c != null) {
if (c.moveToFirst()) {
String address = c.getString(c.getColumnIndex("address"));
String body = c.getString(c.getColumnIndex("body"));
if (mHandler != null) {
mHandler.obtainMessage(MSG_RECEIVED_CODE, new String[]{address, body})
.sendToTarget();
}
Log.i(getClass().getName(), "发件人为:" + address + " " + "短信内容为:" + body);
}
c.close();
}
} catch (SecurityException e) {
Log.e(getClass().getName(), "获取短信权限失败", e);
} catch (Exception e) {
e.printStackTrace();
}
}

主活动类MainActivity.java:

https://github.com/Robin-jiangyufeng/SmsObserverForAndroid/blob/master/Sample/src/main/java/com/robin/lazy/sample/MainActivity.java

主活动中,先创建一个观察者smsObserver并注册到主题中,在注册以后,短信观察者就已经启动短信变化监听,接下只要接收短信,对短信做处理就可以了。

定义一个TextView类型的变量textView, 并实例化。用来显示你想显示的内容,内容可以用setTEXT()方法来设置。

Dexter.checkPermission(new CompositePermissionListener(), Manifest.permission.READ_SMS)为请求权限方法,new CompositePermissionListener()为处理权限请求的回调接口,Manifest.permission.READ_SMS为请求的权限,即读取短信。

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
smsObserver=new SmsObserver(this,this,new VerificationCodeSmsFilter("180"));
smsObserver.registerSMSObserver();
textView=(TextView)findViewById(R.id.textView);
Dexter.checkPermission(new CompositePermissionListener(), Manifest.permission.READ_SMS);
}

覆写了onCallbackSmsContent()方法,即修改自动回复的短信的内容:

public void onCallbackSmsContent(String code) {
textView.setText("短信验证码:"+code);
}

Android短信过滤项目中的观察者模式的更多相关文章

  1. Android短信监听实现,及Android4.4之后短信机制变更

    前阵子公司有一个项目,简单的监听短信应用,功能只有如下两个: 1.监听短信并获取短信内容上传服务器: 2.从服务器获取短信内容,发送出去    按照传统的思路,监听短信我们有两种方式:第一种是使用广播 ...

  2. 【mob】Android短信验证+源码

    在很多的应用当中,都涉及到了短信验证的功能,比如在注册或者找回密码的时候,那么我们如何通过第三方的平台来完成这个功能呢? 本面博文就实现短信验证,来做一个小的栗子. 第一步-下载开发包 第二步-将SD ...

  3. Android 短信验证码控件

    Android 短信验证码控件,便于项目中使用统一样式,统一提示改动.个人觉得挺好用的 <span style="font-size:18px;">public cla ...

  4. Android 短信的还原

    上篇文章讲到<Android 短信的备份>,本文主要实现Android 短信的还原,即是将一条 布局文件: <RelativeLayout xmlns:android="h ...

  5. Android短信彩信收发流程(应用层)

    下图为ComposeMessageActivity中confirmSendMessageIfNeeded部分的信息发送流程.主要以接收者有效性的确认为主,然后转向sendMessage方法进行发送. ...

  6. Android短信备份及插入笔记

    实现备份短信到xml文件和像短信中插入一条数据 一.实现短信将备份到xml文件中 在布局文件中定义一个按钮,定义点击事件为copyClick MainActivity.java: package co ...

  7. Android短信发送器(2)

    在上一篇的<Android短信发送器>当中.发送功能并不完好.当发送内容超过限定字数时,短信就会发送失败,此时就须要推断内容是否超过限制,假设不超过限制.就直接发送,反之.则对其进行处理再 ...

  8. Android安卓电话拦截及短信过滤

    package com.focus.manager; import java.lang.reflect.Method; import Android .app.Activity; import And ...

  9. Android 短信广播接收相关问题

    本人是Android新手,最近做了一个关于监听手机短信功能的应用,我在网上看资料了解到广播分为有序广播和无序广播,有序广播:无序广播又称普通广播,其中的利弊我也一时没搞清楚,我用的是有序广播实现的,具 ...

随机推荐

  1. c# 纯代码调用 webservice

    public static class RequestHelper { public class RequestResult { public RequestResult(bool requestRe ...

  2. 多个字符串有相同的hashcode(没见到大于8的时候转成红黑树)

    public static void main(String[] a){ byte[] b1 = {33 , 123 ,124}; byte[] b2 = {33 , 124 , 93}; byte[ ...

  3. HI3518EV200+AR0130开发板烧录uboot、kernel、rootfs及其参数配置

    分区名 分区大小 起始地址 截至地址bootloader:1M 0x00000000 0x00100000kernel: 3M 0x00100000 0x00400000rootfs: 12M 0x0 ...

  4. python之 自动补全 tab

    1.在python中运行命令sys.path查看python路径 >>> import sys>>> import tabTraceback (most recen ...

  5. Vue.js 父子组件之间通信的方式

    Vue 父子组件之间的同学有一下几种方式: 1. props 2. $emit -- 组件封装用的比较多 3. .sync -- 语法糖 4. $attrs 和 $listeners -- 组件封装用 ...

  6. python selenium-webdriver 等待时间(七)

    测试过程中,我们经过发现脚本执行的时候展现出来的效果都是很快结束了,为了观察执行效果我们会增加一个等待时间来观察一下执行效果.这种等待时间我们只是为了我们便于观察,这种情况下是否包含等待时间不会影响我 ...

  7. .net core 存储base64的图片或文件

    public void SaveImageFromBase64(string base64string) { byte[] b = Convert.FromBase64String(base64str ...

  8. IDEA下调试和运行Hadoop程序例子

    准备 配置好JDK和Hadoop环境, 在IDEA中建立maven项目,建立后的目录结构为: 修改pom..xml引入相关支持: <?xml version="1.0" en ...

  9. SpringBoot启动源码探究---listeners.starting()

    1.首先调用starting()方法,其内部是一个对所有listener的starting()调用的for循环,然后每个listener调用另一个starting方法,其内部调用multicastEv ...

  10. H264--2--语法及结构

    转自:http://blog.csdn.net/yangzhongxuan/article/details/8003494 名词解释 场和帧 :    视频的一场或一帧可用来产生一个编码图像.在电视中 ...