Android两种方式监听短信内容---BroadcastReceiver和ContentObserver
2016-12-28 18:48
549 查看
监听短信:
ContentObserver:监听短信数据库的变化
BroadCastReceiver:通过广播接收器来实现监听
拦截垃圾短信:用广播,如果用ContentObserver,垃圾短信已经存到收件箱了 用广播要考虑优先级不如第三方软件会被拦截
监 听 短 信:用ContentObserver,用广播如果短信长会被切割成多条
第一种方式:广播
SMSBroadcastReceiver:
第二种方法:数据库读取短信记录:
MainActivity:
动态注册广播:写一个SMSBroadcastReceiver类
用ManageQuery还是不行 Android5.1系统魅族手机通知类短信读不到验证码
Android 6.0小米系统所有通知类短信都读不到
代码:
package com.miapsoft.intercept_mmsdemo.activity;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.example.intercept_mmsdemo.R;
import android.app.Activity;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.widget.EditText;
public class MainActivity extends Activity{
EditText ed_mmscode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ed_mmscode=(EditText) findViewById(R.id.ed_mms);
SmsContent content = new SmsContent(new Handler());
//注册短信变化监听
this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, content);
}
/**
* 监听短信数据库
*/
class SmsContent extends ContentObserver {
private Cursor cursor = null;
public SmsContent(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//读取收件箱中指定号码的短信
cursor = managedQuery(Uri.parse("content://sms/inbox"), new String[]{"_id", "address", "read", "body"}, " address=? and read=?", new String[]{"10658464", "0"}, "_id desc");//按id排序,如果按date排序的话,修改手机时间后,读取的短信就不准了
if (cursor != null && cursor.getCount() > 0) {
ContentValues values = new ContentValues();
values.put("read", "1"); //修改短信为已读模式
cursor.moveToNext();
int smsbodyColumn = cursor.getColumnIndex("body");
String smsBody = cursor.getString(smsbodyColumn);
ed_mmscode.setText(getDynamicPassword(smsBody));
}
//在用managedQu
aff8
ery的时候,不能主动调用close()方法, 否则在Android 4.0+的系统上, 会发生崩溃
if(Build.VERSION.SDK_INT < 14) {
cursor.close();
}
}
}
/**
* 从字符串中截取连续6位数字
* 用于从短信中获取动态密码
* @param str 短信内容
* @return 截取得到的6位动态密码
*/
public static String getDynamicPassword(String str) {
Pattern continuousNumberPattern = Pattern.compile("[0-9\\.]+");
Matcher m = continuousNumberPattern.matcher(str);
String dynamicPassword = "";
while(m.find()){
if(m.group().length() == 6) {
System.out.print(m.group());
dynamicPassword = m.group();
}
}
return dynamicPassword;
}
}
ContentObserver:监听短信数据库的变化
BroadCastReceiver:通过广播接收器来实现监听
拦截垃圾短信:用广播,如果用ContentObserver,垃圾短信已经存到收件箱了 用广播要考虑优先级不如第三方软件会被拦截
监 听 短 信:用ContentObserver,用广播如果短信长会被切割成多条
第一种方式:广播
SMSBroadcastReceiver:
package com.ddgl.ddlx.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telephony.SmsMessage; import android.util.Log; import java.text.SimpleDateFormat; import java.util.Date; /** * Created by 27c1 on 2016/12/27. */ public class SMSBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "smsreceiver"; private String ss; private static MessageListener mMessageListener; @Override public void onReceive(Context context, Intent intent) { Log.i(TAG, "onReceive: " + "收到短信广播"); Bundle bundle = intent.getExtras(); SmsMessage msg = null; if (null != bundle) { Object[] smsObj = (Object[]) bundle.get("pdus"); for (Object object : smsObj) { msg = SmsMessage.createFromPdu((byte[]) object); Date date = new Date(msg.getTimestampMillis());//时间 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String receiveTime = format.format(date); Log.i(TAG, "onReceive:===="+"number:" + msg.getOriginatingAddress() + " body:" + msg.getDisplayMessageBody() + " time:" + msg.getTimestampMillis()); if (msg.getDisplayMessageBody().substring(0,9).equals("【丁丁旅行】验证码")){ ss = msg.getDisplayMessageBody().substring(9, 15); Log.i(TAG, "onReceive: 截取的为==="+ ss); if (ss.length()==6){ mMessageListener.onReceived(ss); abortBroadcast(); } } } } } //回调接口 public interface MessageListener { public void onReceived(String message); } public void setOnReceivedMessageListener(MessageListener messageListener) { this.mMessageListener = messageListener; } }MainActiivty:动态注册广播并修改edittext内容
@Override public void onStart() { super.onStart(); receiver = new SMSBroadcastReceiver(); IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); filter.setPriority(Integer.MAX_VALUE); getActivity().registerReceiver(receiver, filter); receiver.setOnReceivedMessageListener(new SMSBroadcastReceiver.MessageListener() { @Override public void onReceived(String message) { etLoginName.setText(message); } }); } //注销短信监听广播 @Override public void onDestroy() { super.onDestroy(); getActivity().unregisterReceiver(receiver); }短信权限:
<!--短信权限--> <uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.SEND_SMS"/> <uses-permission android:name="android.permission.READ_SMS" />但是这个方法Android 5.1系统魅族手机可以 Android4.3系统oppo手机不可以
第二种方法:数据库读取短信记录:
MainActivity:
private SMSObserver observer; //点击完获取验证码就开始读取数据库 observer = new SMSObserver(getActivity(), smsHandler); getActivity().getContentResolver().registerContentObserver(SMS_INBOX, true, observer); //读取短信内容handler private Handler smsHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.i(TAG, "handleMessage: msg===" + msg.obj); String autoCode = (String) msg.obj; etLoginName.setText(autoCode); } }; @Override public void onDestroy() { super.onDestroy(); getActivity().getContentResolver().unregisterContentObserver(observer); }SMSObserver:
package com.ddgl.ddlx.ContentObserver; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Handler; import android.os.Message; import android.util.Log; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.ddgl.ddlx.fragment.LoginNoPassFragment.getCodeTime; /** * Created by 27c1 on 2016/12/29. */ public class SMSObserver extends ContentObserver { private static final String TAG = "smsobserver"; private Context context; public static Uri SMS_INBOX = Uri.parse("content://sms/"); private Handler handler = new Handler(); /** * Creates a content observer. * * @param handler The handler to run {@link #onChange} on, or null if none. */ public SMSObserver(Context context, Handler handler) { super(handler); this.context = context; this.handler = handler; } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); //每当有新短信到来时,使用我们获取短消息的方法 getSmsFromPhone(); } private void getSmsFromPhone() { ContentResolver cr = context.getContentResolver(); String[] projection = new String[]{"body"};//"_id", "address", "person",, "date", "type String where = " date > " + getCodeTime; Cursor cursor = cr.query(SMS_INBOX, projection, where, null, "date desc"); if (cursor != null) { if (cursor.moveToNext()) { String body = cursor.getString(cursor.getColumnIndex("body")); Log.i(TAG, "getSmsFromPhone:短信内容===" + body); if (body.contains("XXX验证码")) { //这里我是要获取自己短信服务号码中的验证码~~ String regEx = "[^0-9]"; Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(body); String num = m.replaceAll("").trim().toString(); Log.i(TAG, "getSmsFromPhone: num===" + num); if (num != null) { Message message = new Message(); message.obj = num; handler.sendMessage(message); } } else { Log.i(TAG, "getSmsFromPhone: " + "没有收到XXX的短信"); } } } else { return; } } }
动态注册广播:写一个SMSBroadcastReceiver类
SMSBroadcastReceiver receiver = new SMSBroadcastReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction("android.provider.Telephony.SMS_RECEIVED"); filter.setPriority(Integer.MAX_VALUE); getActivity().registerReceiver(receiver, filter);静态注册广播:
<receiver android:name=".BroadcastReceiver.SMSBroadcastReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>数据库读取短信:
用ManageQuery还是不行 Android5.1系统魅族手机通知类短信读不到验证码
Android 6.0小米系统所有通知类短信都读不到
代码:
package com.miapsoft.intercept_mmsdemo.activity;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.example.intercept_mmsdemo.R;
import android.app.Activity;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.widget.EditText;
public class MainActivity extends Activity{
EditText ed_mmscode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ed_mmscode=(EditText) findViewById(R.id.ed_mms);
SmsContent content = new SmsContent(new Handler());
//注册短信变化监听
this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, content);
}
/**
* 监听短信数据库
*/
class SmsContent extends ContentObserver {
private Cursor cursor = null;
public SmsContent(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//读取收件箱中指定号码的短信
cursor = managedQuery(Uri.parse("content://sms/inbox"), new String[]{"_id", "address", "read", "body"}, " address=? and read=?", new String[]{"10658464", "0"}, "_id desc");//按id排序,如果按date排序的话,修改手机时间后,读取的短信就不准了
if (cursor != null && cursor.getCount() > 0) {
ContentValues values = new ContentValues();
values.put("read", "1"); //修改短信为已读模式
cursor.moveToNext();
int smsbodyColumn = cursor.getColumnIndex("body");
String smsBody = cursor.getString(smsbodyColumn);
ed_mmscode.setText(getDynamicPassword(smsBody));
}
//在用managedQu
aff8
ery的时候,不能主动调用close()方法, 否则在Android 4.0+的系统上, 会发生崩溃
if(Build.VERSION.SDK_INT < 14) {
cursor.close();
}
}
}
/**
* 从字符串中截取连续6位数字
* 用于从短信中获取动态密码
* @param str 短信内容
* @return 截取得到的6位动态密码
*/
public static String getDynamicPassword(String str) {
Pattern continuousNumberPattern = Pattern.compile("[0-9\\.]+");
Matcher m = continuousNumberPattern.matcher(str);
String dynamicPassword = "";
while(m.find()){
if(m.group().length() == 6) {
System.out.print(m.group());
dynamicPassword = m.group();
}
}
return dynamicPassword;
}
}
相关文章推荐
- Android中的ViewRootImpl类源码解析
- Android 图片压缩的那些事
- Android短信发送器
- Android 安卓编程规范
- 抓取ANR log的方法
- 为什么需要学Gradle?
- Android开发误删文件找回的方法
- Kotlin+Anko 你应该尝试的新Android开发方式
- RelativeLayout的属性
- android之利用activity进行弹窗dialog显示版本更新
- 推荐一个Android开发懒人库 -- ButterKnife
- Android开发之自定义圆形的ImageView的实现
- Android中圆形图的几种实现方式
- Android Scroller与computeScroll的调用机制关系
- 融云 SDK 集成详解 – Android Studio
- RecyclerView+GridView分组效果
- android studio快捷键
- Android下拉刷新上拉加载记录
- Android studio 二维码开源项目ZXing使用详解
- Android 自定义注解