获取短信内容

2024-08-26 05:32
文章标签 获取 短信内容

本文主要是介绍获取短信内容,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近做的项目里要监听手机的短消息内容,这个东西好像在最初学的时候都做过,不过现在早忘记了,现在写下来,记住了。



前提--权限:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <uses-permission android:name="android.permission.RECEIVE_SMS" >  
  2. </uses-permission>  
  3. <uses-permission android:name="android.permission.READ_SMS" >  
  4. </uses-permission>  


方式一:通过广播监听短信消息

(注意:这种方式只对新收到的短消息有效,运行代码,并不会读取收件箱中已读或未读的消息,只有当收到新来的短消息时,才会执行onChange方法)


注册一个广播:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <receiver android:name="com.dbjtech.acbxt.waiqin.SmsReciver" >  
  2.            <intent-filter android:priority="999">  
  3.                <action android:name="android.provider.Telephony.SMS_RECEIVED" />  
  4.            </intent-filter>  
  5.        </receiver>  

SmsReceiver.java

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class SmsReciver extends BroadcastReceiver {  
  2.   
  3.     @Override  
  4.     public void onReceive(Context context, Intent intent) {  
  5.         Bundle bundle = intent.getExtras();  
  6.         SmsMessage msg = null;  
  7.         if (null != bundle) {  
  8.             Object[] smsObj = (Object[]) bundle.get("pdus");  
  9.             for (Object object : smsObj) {  
  10.                 msg = SmsMessage.createFromPdu((byte[]) object);  
  11.             Date date = new Date(msg.getTimestampMillis());//时间  
  12.                 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  13.                 String receiveTime = format.format(date);  
  14.                 System.out.println("number:" + msg.getOriginatingAddress()  
  15.                 + "   body:" + msg.getDisplayMessageBody() + "  time:"  
  16.                         + msg.getTimestampMillis());  
  17.                   
  18.                 //在这里写自己的逻辑  
  19.                 if (msg.getOriginatingAddress().equals("10086")) {  
  20.                     //TODO  
  21.                       
  22.                 }  
  23.                   
  24.             }  
  25.         }  
  26.     }  
  27.   
  28. }  


系统的这个广播是有序广播,就是当别的程序先获取到了这个广播再传递给你,当然它也可以干掉这个广播,让你接收不到,这样你的程序肯定是接收不到这个广播的了。我们发现,通过设置priority的数值,其实有时是不管用的,现在在一些定制的系统或是有安全软件的情况下,往往短消息都被截取到,并被干掉。

那么,我们只能使用方法二,监听短信数据库的变化,这种方式比方法一稍微复杂一些,不过使用起来也很方便,不受其它程序干扰~


方式二:通过短信数据库获取短信内容

(注意:这种方式可以获取手机上所有的短信,包括已读未读的短信,是不是很赞)

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private Uri SMS_INBOX = Uri.parse("content://sms/");  
  2.     public void getSmsFromPhone() {  
  3.         ContentResolver cr = getContentResolver();  
  4.         String[] projection = new String[] { "body" };//"_id", "address", "person",, "date", "type  
  5.         String where = " address = '1066321332' AND date >  "  
  6.                 + (System.currentTimeMillis() - 10 * 60 * 1000);  
  7.         Cursor cur = cr.query(SMS_INBOX, projection, where, null"date desc");  
  8.         if (null == cur)  
  9.             return;  
  10.         if (cur.moveToNext()) {  
  11.             String number = cur.getString(cur.getColumnIndex("address"));//手机号  
  12.             String name = cur.getString(cur.getColumnIndex("person"));//联系人姓名列表  
  13.             String body = cur.getString(cur.getColumnIndex("body"));  
  14.             //这里我是要获取自己短信服务号码中的验证码~~  
  15.             Pattern pattern = Pattern.compile(" [a-zA-Z0-9]{10}");  
  16.             Matcher matcher = pattern.matcher(body);  
  17.             if (matcher.find()) {  
  18.                 String res = matcher.group().substring(111);  
  19.                 mobileText.setText(res);  
  20.             }  
  21.         }  
  22.     }  




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:短信服务中心号码编号,如+8613800755500


通过方式二,我们就能获取手机中所有的短消息了,可是还有一个问题,如果来了新的短消息呢?我们总不能写个线程,每隔多少秒,去读取一下短信数据库吧?其实我们可以把方式二换个方式写:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private SmsObserver smsObserver;  
  2.   
  3.     protected void onCreate(Bundle savedInstanceState) {  
  4.         super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.app_login);  
  6.         smsObserver = new SmsObserver(this, smsHandler);  
  7.         getContentResolver().registerContentObserver(SMS_INBOX, true,  
  8.                 smsObserver);  
  9.   
  10.     }  
  11.     public Handler smsHandler = new Handler() {  
  12.         //这里可以进行回调的操作  
  13.         //TODO  
  14.   
  15.     };  
  16.     class SmsObserver extends ContentObserver {  
  17.   
  18.         public SmsObserver(Context context, Handler handler) {  
  19.             super(handler);  
  20.         }  
  21.   
  22.         @Override  
  23.         public void onChange(boolean selfChange) {  
  24.             super.onChange(selfChange);  
  25.             //每当有新短信到来时,使用我们获取短消息的方法  
  26.             getSmsFromPhone();  
  27.         }  
  28.     }  



效果:



这篇关于获取短信内容的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1107683

相关文章

python获取当前文件和目录路径的方法详解

《python获取当前文件和目录路径的方法详解》:本文主要介绍Python中获取当前文件路径和目录的方法,包括使用__file__关键字、os.path.abspath、os.path.realp... 目录1、获取当前文件路径2、获取当前文件所在目录3、os.path.abspath和os.path.re

Java子线程无法获取Attributes的解决方法(最新推荐)

《Java子线程无法获取Attributes的解决方法(最新推荐)》在Java多线程编程中,子线程无法直接获取主线程设置的Attributes是一个常见问题,本文探讨了这一问题的原因,并提供了两种解决... 目录一、问题原因二、解决方案1. 直接传递数据2. 使用ThreadLocal(适用于线程独立数据)

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR

JS和jQuery获取节点的兄弟,父级,子级元素

原文转自http://blog.csdn.net/duanshuyong/article/details/7562423 先说一下JS的获取方法,其要比JQUERY的方法麻烦很多,后面以JQUERY的方法作对比。 JS的方法会比JQUERY麻烦很多,主要则是因为FF浏览器,FF浏览器会把你的换行也当最DOM元素。 <div id="test"><div></div><div></div

vcpkg子包路径批量获取

获取vcpkg 子包的路径,并拼接为set(CMAKE_PREFIX_PATH “拼接路径” ) import osdef find_directories_with_subdirs(root_dir):# 构建根目录下的 "packages" 文件夹路径root_packages_dir = os.path.join(root_dir, "packages")# 如果 "packages"

Weex入门教程之4,获取当前全局环境变量和配置信息(屏幕高度、宽度等)

$getConfig() 获取当前全局环境变量和配置信息。 Returns: config (object): 配置对象;bundleUrl (string): bundle 的 url;debug (boolean): 是否是调试模式;env (object): 环境对象; weexVersion (string): Weex sdk 版本;appName (string): 应用名字;

MFC中App,Doc,MainFrame,View各指针的互相获取

纸上得来终觉浅,为了熟悉获取方法,我建了个SDI。 首先说明这四个类的执行顺序是App->Doc->Main->View 另外添加CDialog类获得各个指针的方法。 多文档的获取有点小区别,有时间也总结一下。 //  App void CSDIApp::OnApp() {      //  App      //  Doc     CDocument *pD

android两种日志获取log4j

android   log4j 加载日志使用方法; 先上图: 有两种方式: 1:直接使用架包 加载(两个都要使用); 架包:android-logging-log4j-1.0.3.jar 、log4j-1.2.15.jar  (说明:也可以使用架包:log4j-1.2.17.jar)  2:对架包输入日志的二次封装使用; 1:直接使用 log4j 日志框架获取日志信息: A:配置 日志 文

17 通过ref代替DOM用来获取元素和组件的引用

重点 ref :官网给出的解释是: ref: 用于注册对元素或子组件的引用。引用将在父组件的$refs 对象下注册。如果在普通DOM元素上使用,则引用将是该元素;如果在子组件上使用,则引用将是组件实例: <!-- vm.$refs.p will be the DOM node --><p ref="p">hello</p><!-- vm.$refs.child will be the c

react笔记 8-19 事件对象、获取dom元素、双向绑定

1、事件对象event 通过事件的event对象获取它的dom元素 run=(event)=>{event.target.style="background:yellowgreen" //event的父级为他本身event.target.getAttribute("aid") //这样便获取到了它的自定义属性aid}render() {return (<div><h2>{