您的位置:首页 > 移动开发 > Android开发

Android 短信监听

2016-03-11 10:40 323 查看
引用:

参考blog

需求是监听发送短信到手机,手机自动填充验证码,通过实现链接的实现一,发现部分手机不能接收到广播;

通过实现二,成功在小米的机子上实现自动填充验证码;

所以在需求的实现上进行包装。

需要权限

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


实践:

//情况二,自己手动在适合情况下,调用 smsListener.stop(),停止监听;
//SmsListener smsListener = new SmsListener(context)

//情况一,在调用回调函数时,自动停止监听
SmsListener smsListener = new SmsListener(context, true);
smsListener.setMessageReceiveListener(smsListener.new OnMessageReceiveListener()
{
@Override
protected void onMessageReceive(String number, String message)
{
if ("10086".equalsIgnoreCase(number) && null != message && message.length() > 0)
{

int index = message.indexOf("验证码:");
if (index > 0)
{
final String code = message.substring(index + 4, index + 10);
//当需要更新页面时,可能需要在主线程跑,否则需要让控件获得焦点才会更新。
((Activity) context).runOnUiThread(new Runnable()
{
@Override
public void run()
{
veriEdit.setText(code);
}
});
}
}
}
});
smsListener.start();


import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;


/**
* 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:短信服务中心号码编号


public class SmsListener extends ContentObserver
{
private Context context;
private boolean isAutoStop;
private OnMessageReceiveListener messageReceiveListener;
private String[] listenerAddresses; //监听的信息来源,如号码: {"10086","10000"};
private int minutes = 5; //当有新信息来到时,查询多少分钟内来源的信息;如果设置了isAutoStop=true,只会出现最新的一条;
private Uri SMS_INBOX = Uri.parse("content://sms/");

/**
* 当监听到短信,执行完listener后自动停止监听
* @param context
* @param isAutoStop default is false;
* @throws Exception
*/
public SmsListener(Context context, boolean isAutoStop)
{
super(null);
this.context = context;
this.isAutoStop = isAutoStop;
}

/**
* 需要手动调用stop进行 停止,开启监听
* @param context
* @throws Exception
*/
public SmsListener(Context context)
{
this(context, false);
}

@Override
public void onChange(boolean selfChange)
{
super.onChange(selfChange);
handleMessage();
handleMessageCompleted();
}

public void start()
{
context.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, this);
}

public void stop()
{
context.getContentResolver().unregisterContentObserver(this);
}

private void handleMessageCompleted()
{
if (isAutoStop)
{
stop();
}
}

private void handleMessage()
{
if (messageReceiveListener != null)
{
ContentResolver cr = context.getContentResolver();
Cursor cur = querySMS(cr);
if (null != cur)

4000
{
if (cur.moveToNext())
{
StringBuffer b = new StringBuffer();
for (int i = 0; i < cur.getColumnCount(); i++)
{
b.append(cur.getColumnName(i)+":"+cur.getString(i)+" \n ");
}
//projection从数据库读取的字段
String number = cur.getString(cur.getColumnIndex("address"));//手机号
String body = cur.getString(cur.getColumnIndex("body"));
String _id = cur.getString(cur.getColumnIndex("_id"));
messageReceiveListener.onMessageReceive(cur);
messageReceiveListener.onMessageReceive(number, body);
cur.close();
updateSMSRead(cr, _id);
}
}
}
}

private void updateSMSRead(ContentResolver cr, String _id)
{
//将短信设置为已读
ContentValues contentValues = new ContentValues();
contentValues.put("read", 1);
String contentValuesWhere = "_id = '" + _id +"' ";
cr.update(SMS_INBOX, contentValues, contentValuesWhere, null);
}

private Cursor querySMS(ContentResolver cr)
{
//从数据库读取的字段,详见sms主要结构;//"_id", "address", "person", "date", "type"
String[] projection = new String[] { "_id","body", "address" };
StringBuffer addressCondition = new StringBuffer("");
if (listenerAddresses != null)
{
for (String addresses : listenerAddresses)
{
if(addressCondition.length()==0){
addressCondition.append(" ( ");
}
if (addressCondition.length() > 3)
{
addressCondition.append(" OR ");
}
addressCondition.append(" address = '" + addresses + "' ");
}
if (addressCondition.length() > 0)
{
addressCondition.append(" ) AND ");
}
}
String where = addressCondition.toString() + " date >  " + (System.currentTimeMillis() - minutes * 60 * 1000) + " AND type = '1' AND read='0' ";
//初始化查询条件

Cursor cur = cr.query(SMS_INBOX, projection, where, null, "date desc");
return cur;
}

public abstract class OnMessageReceiveListener
{
protected abstract void onMessageReceive(String number, String message);

protected void onMessageReceive(Cursor msg)
{
};
}

public OnMessageReceiveListener getMessageReceiveListener()
{
return messageReceiveListener;
}

public SmsListener setMessageReceiveListener(OnMessageReceiveListener messageReceiveListener)
{
this.messageReceiveListener = messageReceiveListener;
return this;
}

public String[] getListenerNumber()
{
return listenerAddresses;
}

/**
* 缩小了查询范围 , 可以不设置
* @param listenerAddresses
*/
public void setListenerAddresses(String... listenerAddresses)
{
this.listenerAddresses = listenerAddresses;
}

public int getMinutes()
{
return minutes;
}

public void setMinutes(int minutes)
{
this.minutes = minutes;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  验证码 短信 小米