Android短信发送,监听,及其工具类封装
来源:互联网 发布:软件的健壮性 编辑:程序博客网 时间:2024/06/05 16:32
这几天在读ViewPager及相关控件的源码和相关开源的代码,还没构思好比较系统容易理解记忆的文章内容概述,就分享个封装的工具类供同仁们参考一下吧
一,封装 :发送短信
发送短信比较简单,主要有两种实现方式,一种是使用Intent通过系统短信应用,一种是直接调用短信接口发送短信;根据使用场景不同我一共封装了三个方法:
- 调用系统发短信界面 不需要用户自己输入接收方的电话号码
/** * 调用系统发短信界面 不需要用户自己输入接收方的电话号码 * * @param context Activity * @param phoneNumber 手机号码 * @param smsContent 短信内容 */ public static void sendMessageByIntent(Context context, String phoneNumber, String smsContent) { if (phoneNumber == null || phoneNumber.length() < 4) { return; } Uri uri = Uri.parse("smsto:" + phoneNumber); Intent intent = new Intent(Intent.ACTION_SENDTO, uri); intent.putExtra("sms_body", smsContent); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (intent.resolveActivity(context.getPackageManager()) != null) { context.startActivity(intent); } }
- 调用系统发短信界面,需要用户自己输入接收方的电话号码
/** 调用系统发短信界面,需要用户自己输入接收方的电话号码 * * 示例:SMSUtil.sendMessageByIntent(MainActivity.this,"你好"); * * @param context * @param message */ public static void sendMessageByIntent(Context context, String message) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.putExtra("sms_body", message); intent.setType("vnd.android-dir/mms-sms"); if (intent.resolveActivity(context.getPackageManager()) != null) { context.startActivity(intent); } }
- 直接调用短信接口发短信
/** * 直接调用短信接口发短信 * @param ActivityOrSetvice Activity * @param phoneNumber * @param smsContent */ public static void sendMessageBySysterm(Context ActivityOrSetvice, String phoneNumber, String smsContent) { if (phoneNumber == null || phoneNumber.length() < 4) { return; } //获取短信管理器 android.telephony.SmsManager smsManager = android.telephony.SmsManager.getDefault(); //拆分短信内容(手机短信长度限制) List<String> divideContents = smsManager.divideMessage(smsContent); for (String text : divideContents) { smsManager.sendTextMessage(phoneNumber, null, text, null, null); } }
别忘记了添加权限:<uses-permission android:name="android.permission.SEND_SMS" />
二,通过BroadcastReceiver监听短信的代码
此段代码实现的是通过监听sms广播,把或得到指定号码的短信内容传给声明的TextView,为什么是TextView呢,因为几乎所有有setText()或android:setText=”“属性的View都是TextView的子类(或间接子类)。
/** * 原理: * Android收到短信后系统会发送一个android.provider.Telephony.SMS_RECEIVED广播。 * 把它放在Bundle(intent.Extras)中,Bundle可以理解为一个Map,短信采用"pdus"作为键, * pdus应该是protocol description units的简写,也就是一组短信。 * Android不是一接收到短信就立刻发出广播,会有一定的延迟, * 所以就有可能有多条短信,所以才会用数组来存放。 */import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.telephony.SmsMessage;import android.widget.TextView;/** * 作者:liuyaowei ;日期:2016-07-16. * QQ:1054185214 * 类作用:监听短信广播, 获取短信 */public class SmsBroadcastReceiver extends BroadcastReceiver { private String address=null; //需要监听的号码 private TextView text ; public SmsBroadcastReceiver(String address, TextView text) { this.address=address; this.text=text; } @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); SmsMessage[] smsMessages = null; Object[] pdus = null; if (bundle != null) { pdus = (Object[]) bundle.get("pdus"); } if (pdus !=null){ smsMessages = new SmsMessage[pdus.length]; String sender = null; String content = null; for (int i=0; i<pdus.length; i++){ smsMessages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); sender = smsMessages[i].getOriginatingAddress(); // 获取短信的发送者 content = smsMessages[i].getMessageBody(); // 获取短信的内容 if (sender.equals(address)){ //如果收到信息的号码和指定的号码相同 text.setText(content); //返回信息内容 break; } } } }}
三,通过ContentObserver监听短信的代码
ContentObserver,是Android实现的内容观察者其中一个实现(与另一类DataSetObservable都是抽象类ContentObserver的实现),目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理。这个是我在曾经看到并收集的认为较好代码实现,和上一个功能类似,更进一步处理短信内容得到验证码中的数字,稍加修改,把得到的验证码同样传入TextView中。
/** * 为了减少用户的操作步骤,在获得短信验证码的时候,我们可以监听特殊手机号码的短信, * 截取信息当中的短信验证码(其实有很多应用都监听短信例如360短信,一些信用卡或者是记账类的应用)。 * * 原理:可以使用一个自定义的BroadcastReceiver来监听短信,在监听结果当中过滤手机号, * 在需要回填的activity当中实现实例化广播并且实现其回调接口,在接口当中进行回填验证码, * 在销毁activity时销毁链接。但是这样操作会出现一些问题, * 由于一些其他的应用也会使用广播监听手机例如QQ通讯录或者是360通讯录等有的时候会被其拦截, * 即使修改优先级也会出现不能进行回填的问题。所有这里可以采用另外一种的解决方法: * 使用ContentProvider来监听短信数据库的变化, * 在自定义的ContentObserver当中实现onChange的方法进行监听特定手机号的短信, * 然后进行信息截取在填充到需要填充的位置。 * * “ContentObserver,内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理, * 它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。 * 触发器分为表触发器、行触发器,相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver, * 当然这是与它所监听的Uri MIME Type有关的。” * * 摘自:自动填充短信验证码(使用ContentObserver):http://www.tuicool.com/articles/bMVRru */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.Handler;import android.widget.EditText;import android.widget.TextView;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * 作者:liuyaowei ;日期:2016-07-16. * QQ:1054185214 * 类作用:监听短信数据库, 获取短信 验证码 */public class SmsContentObserver extends ContentObserver { private Activity activity; private String address; private TextView text; public SmsContentObserver(Handler handler, Activity activity, String number, TextView text) { super(handler); this.activity=activity; this.address=number; this.text=text; } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); // 读取收件箱中指定号码的短信// content://sms/inbox 收件箱// content://sms/sent 已发送// content://sms/draft 草稿// content://sms/outbox 发件箱// content://sms/failed 发送失败// content://sms/queued 待发送列表 Cursor cursor= activity.managedQuery(Uri.parse("content://sms/inbox"), new String[]{"_id","address","body","read"}, " address=? and read=?", new String[] { address, "0" }, "_id desc"); // 按id排序,如果按date排序的话,修改手机时间后,读取的短信就不准了 if (cursor!=null&&cursor.getCount()>0){ ContentValues values=new ContentValues(); if (Build.VERSION.SDK_INT < 21){ values.put("type",1);//修改短信为已读短信 5.0后以不能修改 } cursor.moveToNext(); int smsbodyColumn=cursor.getColumnIndex("body"); String smsbody=cursor.getString(smsbodyColumn); text.setText(getDynamicPassword(smsbody)); //调用下面的截取短信中六位数字验证码的方法 } // 在用managedQuery的时候,不能主动调用close()方法, 否则在Android 4.0+的系统上, 会发生崩溃 if (Build.VERSION.SDK_INT < 14) { cursor.close(); } } /** * 从字符串中截取连续6位数字组合 ([0-9]{" + 6 + "})截取六位数字 进行前后断言不能出现数字 用于从短信中获取动态密码 * * @param st 短信内容 * @return 截取得到的6位动态密码 */ public String getDynamicPassword(String st){ // 6是验证码的位数一般为六位 如果验证码的位数变化只要将6修改为想要的位数, // 过验证如果不止为数字,直接修改正则为想要的内容即可 //Pattern是java.util.regex(一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包)中的一个类。 // 一个Pattern是一个正则表达式经编译后的表现模式 Pattern pattern=Pattern.compile("(?<![0-9])([0-9]{" + 6 + "})(?![0-9])") ; Matcher matcher=pattern.matcher(st); String dynamicPassword=null; while (matcher.find()){ System.out.println(matcher.group()); dynamicPassword=matcher.group(); } return dynamicPassword; }}
四,对上面BroadcastReceiver,ContentObserver注册取消监听的封装
对BroadcastReceiver注册和取消监听的封装:
static BroadcastReceiver receiver; /** * 供其它组件调用 注册短信变化监听 * @param context */ public static void registerSmsBroadcastReceiver(Activity context,String number,TextView text){ if (receiver!=null){ return; } receiver= new SmsBroadcastReceiver(number,text); //注册短信变化监听 context.registerReceiver(receiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED")); } /** * 供其它组件调用 关闭数据库监听 * @param context */ public static void unregisterSmsBroadcastReceiver(Activity context){ if (receiver!=null) { //关闭数据库监听 context.unregisterReceiver(receiver); } }
对ContentObserver注册和取消监听的封装:static SmsContentObserver content; /** * <uses-permission android:name="android.permission.RECEIVE_SMS" /> * 供其它组件调用 注册短信变化监听 * @param context */ public static void registerSmsContentObserver(Activity context,String number,TextView text){ if (content!=null){ return; } content= new SmsContentObserver(new Handler(),context,number,text); //注册短信变化监听 context.getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, content); } /** * 供其它组件调用 关闭数据库监听 * @param context */ public static void unregisterSmsContentObserver(Activity context){ if (content!=null) { //关闭数据库监听 context.getContentResolver().unregisterContentObserver(content); } }
五,不要忘记添加权限
我把这些封装的代码都放到SmsPhoneUtil.java工具类中,在使用中直接通过SmsPhoneUtil调用相关方法就可以了,很方便吧,不过在发送短信和监听短信的时候千万不要忘记添加相应权限。
还有一个通过反射修改短信数据库的示例,还没比较满意的封装,就暂不贴出来了,留待以后仔细研究之后再说。/** * 作者:liuyaowei ;日期:2016-07-14. * QQ:1054185214 * 类作用:Sms and Phone工具类 */public class SmsPhoneUtil { private BitmapUtil() { throw new Error("Do not instantiate it!/不要实例化"); }} <!-- 发送短信 --> <uses-permission android:name="android.permission.SEND_SMS"/> <!-- 读取短信 --> <uses-permission android:name="android.permission.READ_SMS"/> <!-- 接收短信 --> <uses-permission android:name="android.permission.RECEIVE_SMS"/>
0 0
- Android短信发送,监听,及其工具类封装
- Android短信发送,监听,及其工具类封装
- Android监听发送短信
- Android外部监听类-发送短信程序
- android短信监听工具
- Android-短信监听工具
- android短信监听工具
- 短信发送类封装
- android如何监听发送短信
- android如何监听发送短信?
- android发送短信以及监听发送状态
- Android发送短信以及监听发送状态
- Android发送短信以及监听发送状态
- 发送短信工具类
- 短信发送工具类
- [Android实例] android如何监听发送短信?
- (转)android如何监听发送短信
- android 监听 系统message app 短信发送
- 如何理解BGP同步规则-
- HTML特殊字符的html、js、css写法汇总
- Makefile (三) 总述
- Git命令行下自动保存用户名和密码
- [主席树区间覆盖 线段树] UNR #1 火车管理
- Android短信发送,监听,及其工具类封装
- ubuntu14.04系统相关
- Spark 源码解析 : DAGScheduler中的DAG划分与提交
- 转义字符
- UIProgressView 进度表
- IO
- APUE 8-1 fork函数实例
- 【嵌入式学习日记】2016年7月19日
- CC2540协议栈下开发流程