文档章节

android 短信的各种操作操作

We911
 We911
发布于 2017/02/08 10:14
字数 2110
阅读 2
收藏 0
点赞 0
评论 0

android学习笔记25--------------短信的各种操作操作

分类: android 2012-02-17 20:08  2234人阅读  评论(2)  收藏  举报

转载请注明原文出处:http://blog.csdn.net/yf210yf

1.注册广播接收器 

[java]  view plain copy print ?
  1. <receiver android:name="SMSReceiver">  
  2.             <intent-filter>  
  3.                 <action android:name="android.provider.Telephony.SMS_RECEIVED" />  
  4.             </intent-filter>  
  5.         </receiver>  

[java]  view plain copy print ?
  1. import android.content.BroadcastReceiver;  
  2. import android.content.Context;  
  3. import android.content.Intent;  
  4. import android.os.Bundle;  
  5. import android.telephony.SmsMessage;  
  6. import android.widget.Toast;  
  7.   
  8. public class SMSReceiver extends BroadcastReceiver {  
  9.       
  10.     public static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";  
  11.       
  12.     @Override  
  13.     public void onReceive(Context context, Intent intent) {  
  14.         if (SMS_RECEIVED.equals(intent.getAction())) {  
  15.             Bundle bundle = intent.getExtras();  
  16.             if (bundle != null) {  
  17.                 Object[] pdus = (Object[]) bundle.get("pdus");  
  18.                 final SmsMessage[] messages = new SmsMessage[pdus.length];  
  19.                 String msg = "";  
  20.                 for (int i = 0; i < pdus.length; i++) {  
  21.                     messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);  
  22.                     msg += messages[i].getMessageBody();  
  23.                 }  
  24.                 Toast.makeText(context, msg, Toast.LENGTH_LONG).show();  
  25.             }  
  26.         }  
  27.     }  
  28.   
  29. }  

2.添加权限 

[java]  view plain copy print ?
  1. <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>  

二、读取收件箱中的短信

1.从数据库中读取,URI为"content://sms/inbox" 

[java]  view plain copy print ?
  1. import android.app.Activity;  
  2. import android.content.ContentResolver;  
  3. import android.database.Cursor;  
  4. import android.net.Uri;  
  5. import android.os.Bundle;  
  6. import android.widget.TextView;  
  7.   
  8. public class MySMSManager extends Activity {  
  9.       
  10.     private TextView textview;  
  11.     /** Called when the activity is first created. */  
  12.     @Override  
  13.     public void onCreate(Bundle savedInstanceState) {  
  14.         super.onCreate(savedInstanceState);  
  15.         setContentView(R.layout.main);  
  16.         textview = (TextView) findViewById(R.id.textview);  
  17.         readShortMessage();  
  18.     }  
  19.       
  20.     public void readShortMessage() {  
  21.         ContentResolver cr = getContentResolver();  
  22.         Cursor cursor = cr.query(Uri.parse("content://sms/inbox"), nullnullnullnull);  
  23.         String msg = "";  
  24.         while(cursor.moveToNext()) {  
  25.             int phoneColumn = cursor.getColumnIndex("address");    
  26.             int smsColumn = cursor.getColumnIndex("body");    
  27.             msg += cursor.getString(phoneColumn) + ":" + cursor.getString(smsColumn) + "\n";  
  28.         }  
  29.         textview.setText(msg);  
  30.     }  
  31. }  

2.添加权限 

[java]  view plain copy print ?
  1. <uses-permission android:name="android.permission.READ_SMS"></uses-permission>  

 附:其它短信的URI和数据库表字段 

[java]  view plain copy print ?
  1. String SMS_URI_ALL =  "content://sms/";   
  2. String SMS_URI_INBOX = "content://sms/inbox";  
  3. String SMS_URI_SENT = "content://sms/sent";      
  4. String SMS_URI_DRAFT = "content://sms/draft";       
  5. String SMS_URI_OUTBOX = "content://sms/outbox";      
  6. String SMS_URI_FAILED = "content://sms/failed";       
  7. String SMS_URI_QUEUED = "content://sms/queued";  


content://sms/inbox 收件箱 
content://sms/sent 已发送 
content://sms/draft 草稿 
content://sms/outbox 发件箱 
content://sms/failed 发送失败 
content://sms/queued 待发送列表

检索数据方法很简单: 
Uri uri = Uri.parse("content://sms/inbox"); 
Cursor cur = this.managedQuery(uri, null, null, null, null); 
if (cur.moveToFirst()) 


 do

 { 
  for(int j = 0; j < cur.getColumnCount(); j++)

  { 
  info = "name:" + cur.getColumnName(j) + "=" + cur.getString(j); 
  Log.i("====>", info); 
  } 
 }while(cur.moveToNext()); 
}




[java]  view plain copy print ?
  1. /* 
  2. _id => 短消息序号 如100   
  3. thread_id => 对话的序号 如100   
  4. address => 发件人地址,手机号.如+8613811810000   
  5. person => 发件人,返回一个数字就是联系人列表里的序号,陌生人为null   
  6. date => 日期  long型。如1256539465022   
  7. protocol => 协议 0 SMS_RPOTO, 1 MMS_PROTO    
  8. read => 是否阅读 0未读, 1已读    
  9. status => 状态 -1接收,0 complete, 64 pending, 128 failed    
  10. type => 类型 1是接收到的,2是已发出    
  11. body => 短消息内容    
  12. service_center => 短信服务中心号码编号。如+8613800755500   
  13. */  


其中,delete方法中支持的协议为:
SMS_ALL 根据参数中的条件删除sms表数据 
SMS_ALL_ID 根据_id删除sms表数据 
SMS_CONVERSATIONS_ID 根据thread_id删除sms表数据,可以带其它条件 
SMS_RAW_MESSAGE 根据参数中的条件删除 raw表 
SMS_STATUS_PENDING 根据参数中的条件删除 sr_pending表 
SMS_SIM 从Sim卡上删除数据
试一下SMS_CONVERSATIONS_ID:"content://sms/conversations/3 ",删除thread_id="3", _id="5"的数据 
在eclipse中的Emulator Control中,以13800给模拟器发送三条数据,然后以13900发送一条 
this.getContentResolver().delete(Uri.parse("content://sms/conversations/3"), "_id=?", new String{"5"}); 
成功删除一条数据。 
在数据库中每个发送者的thread_id虽然一样,但不是固定的,如果把一个发送者的全部数据删除掉, 
然后换一个新号码发送短信时,thread_id是以数据库中最大的id+1赋值的。 


三、打开发送短信界面

[java]  view plain copy print ?
  1. Uri uri = Uri.parse("smsto:13800138000");  
  2.         Intent it = new Intent(Intent.ACTION_SENDTO, uri);  
  3.         it.putExtra("sms_body""The SMS text");  
  4.         startActivity(it);  

四、发送短信

1.通过SmsManager的sendTextMessage(destinationAddress, scAddress, text, sentIntent, deliveryIntent)方法发送

[java]  view plain copy print ?
  1. String msg ="hello";   
  2.         String number = "1234565678";   
  3.         SmsManager sms = SmsManager.getDefault();   
  4.         PendingIntent pi = PendingIntent.getBroadcast(this,0,new Intent(),0);   
  5.         sms.sendTextMessage(number,null,msg,pi,null);  

2.添加权限

[java]  view plain copy print ?
  1. <uses-permission android:name="android.permission.SEND_SMS"></uses-permission>  


五、直接向数据库写短信

[java]  view plain copy print ?
  1. ContentResolver cr = getContentResolver();  
  2.         ContentValues cv = new ContentValues();  
  3.         cv.put("address""13800138000");  
  4.         cv.put("body""hello!");  
  5.         cr.insert(Uri.parse("content://sms/inbox"), cv);  

权限:

[java]  view plain copy print ?
  1. <uses-permission android:name="android.permission.WRITE_SMS"></uses-permission>  

六、监听短信数据库变化

使用ContentObserver ,观察"content://sms"的变化,调用重写的onChange方法,可以监听到短信记录的

变化,这样可以监听发短信,同样也是可以监听收短信的。

[java]  view plain copy print ?
  1. import android.database.ContentObserver;  
  2. import android.os.Handler;  
  3. import android.util.Log;  
  4.   
  5. public class SMSObserver extends ContentObserver {  
  6.   
  7.     public SMSObserver(Handler handler) {  
  8.         super(handler);  
  9.     }  
  10.       
  11.     @Override  
  12.     public void onChange(boolean selfChange) {  
  13.         Log.i("sms""sms");  
  14.     }  
  15.   
  16. }  

然后在Acitivty或Service里注册这个观察者

[java]  view plain copy print ?
  1. getContentResolver().registerContentObserver(Uri.parse("content://sms"),  
  2.                                 truenew SMSObserver(new Handler()));  



Smsmessage.getTimestampMillis() 获得短信发送时间
System.currentTimeMillis()获得系统当前时间
一般短信软件都是获取当前时间
System.currentTimeMillis()改为Smsmessage.getTimestampMillis()
就能读到短信发送时间。

在做读取短信的时候,读取到date字段,需要转换成例如7/21 或者 8:21这种格式,不用手动转换 通过调用相应的类来实现

SimpleDateFormat sfd = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");// 这里我们可以指定可是 例如 MM-DD就是只显示月和日  。。。。

Date date = new Date(Long.parseLong(cursor.getString(cursor.getColumnIndex("date"))));//从短信中获得时间

String time = sfd.format(date); //转换完成的字符串 很简单

dataTextView.setText(time); //显示出来就行了

使用前:


使用后:



[java]  view plain copy print ?
  1. /** 
  2. * 通过电话号码获取姓名 
  3. */  
  4.   
  5.     public String getContactNameFromPhoneNum(Context context, String phoneNum)  
  6.     {  
  7.         String contactName = "";  
  8.         ContentResolver cr = context.getContentResolver();  
  9.         Cursor pCur = cr.query(  
  10.                 ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,  
  11.                 ContactsContract.CommonDataKinds.Phone.NUMBER + " = ?",  
  12.                 new String[]  
  13.                 { phoneNum }, null);  
  14.         if (pCur.moveToFirst())  
  15.         {  
  16.             contactName = pCur  
  17.                     .getString(pCur  
  18.                             .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));  
  19.             pCur.close();  
  20.         }  
  21.         return contactName;  
  22.     }  

Android系统源码数据库(mmssms.db)中几个表之前的关系. 

首先明了未接信息的数据库的位置在系统 

/data/data/com.android.providers.telephony/databases/mmssms.db 包下。 

希望大家能够结合源码中的 

1.       Telephony.java (主要讲这些表里有哪些字段) 

2.       MmsSmsProvider.java (ContentProvider被重写) 

3.       MmsProvider.java (ContentProvider被重写) 

4.       SmsProvider.java (ContentProvider被重写) 

5.       Conversation.java  描述 mmssms数据库的Threads表


当我们查询mmssms.db数据库时,这其中涉及到以下几张表: 

1.       threads表 

2.       存放短信的表(sms表) 

3.       存放彩信的表(pdu表,part表) 

4.       存放phone number的表( Canonical_address表) 

threads表字段说明: 

_id: 用于区分不同的电话号码,系统会为不同的电话号码分配不同的_id. 

date: 收到信息的时间(如果收到来自同一个phone number多条信息,并且有对于一条信息未读,那么date表示收到的最后一条信息时的时间) 

message_count: 收到的信息的数目(sms+mms) 

snippet: 如果来自某个phone number,仅仅有一条信息,那么会是如下情况 

      如果是未接短信,代表未接短信的内容 

      如果是未接彩信,代表未接彩信的subject. 

      如果来自某个phone number,仅仅有多条信息,那么则是如下情况 

      如果是最后一条是未接短信,代表最后一条未接短信的内容 

      如果是最后一条是未接彩信,代表最后一条未接彩信的subject. 

      然而这个字段存储的仅仅是一条短信内容或者彩信subject的部分内容,其余内容用省略号表示。 

read: 0. 代表未读。 1.代表 已读 

has_attchment: 代表来自该phone number的信息是否包含有附件。 

依据上面的表结构,也许会有人问,phone number 呢?有这样的疑问是非常正常的,别着急,学过数据库的人都知道,表结构之间并不是孤立的,而是相互关联的。

phone number 会在另外几张表中出现。






Sms表 

查询该表时的uri :   URI_SMS_INBOX = Uri.parse("content://sms/inbox") 

_id 
thread_id 
address 
date 
read 
subject 
body 
locked 

Sms表字段说明 

_id: 区分不同的短信。 

threads_id: (外键)引用threads表的_id. 

date: 该条短信接收的时间 

read: 0表未读,1表已读 

body: 表示具体的短信内容,(注意,虽然在thread表的snippet字段已经存储了一部分body,但是那里的并不全,仅仅是一部分body) 

locked: 该字段我也不是很清楚,用到的不多,不过如果我标识某条信息为locked时,当我再删除这条信息时,系统会提示我“是否删除locked信息”。 

很明显以上:_id为4.或5的短信,来自同一个phone number,也就是说他们的thread_id是相同的. 


Pdu表: 

URI_MMS_INBOX = Uri.parse("content://mms/inbox"); 

_id 
Thread_id 
date 
Msg_box 
read 
M_id 
sub 
Ct_l 
m_type  

Pdu表字段说明: 

_id: 区分不同的彩信 

thread_id : 外键 (引用thread表的_id) 

msg_box: 区分彩信的收件箱,发件箱,草稿箱等. 

         很明显1.代表收件箱 

read:是否已读,0 未读,1.已读 

sub: 彩信的subject 

ct_l: 如果彩信太大,或者由于网络原因,也又是由于手机设备原因,dowload失败,彩信看不了,这个字段就会有彩信的网址(我曾经见到过一次,http://格式的,就是一个网址)

本文转载自:http://blog.csdn.net/liduanw/article/details/8461973

共有 人打赏支持
We911
粉丝 0
博文 63
码字总数 0
作品 0
深圳
程序员
Android push (一):SMS push

Android push (一):SMS push 移动终端为了节省电量和网络流量,不再采用轮训服务器的方式来收集数据,而是在服务器有数据需要发送到终端时通知终端。我们称这种机制叫推送(push)。终端接...

LiSteven
2013/06/04
0
1
新型银行木马病毒MysteryBot Android深度分析

  近日,国外某安全公司发现一种新型银行木马病毒MySteryBot Android,该病毒为银行木马LokiBot Android的变种,其恶意行为除了利用银行木马窃取金融信息外,还包括恶意监视键盘、植入勒索...

FreeBuf
07/16
0
0
Android DDMS如何使用?

DDMS 的全称是Dalvik Debug Monitor Service,它为我们提供例如:为测试设备截屏,针对特定的进程查看正在运行的线程以及堆信息、Logcat、广播状态信息、模拟电话呼叫、接收 SMS、虚拟地理坐...

Kevin_Gan
2010/08/19
0
1
Android中短信拦截解决方案

Android中短信拦截解决方案 经过测试,Android中是可以拦截短信的,解决方案如下: package com.tigertian.sms; import android.content.BroadcastReceiver; import android.content.Contex...

塔塔米
2014/02/16
0
0
Android层次化安全架构及核心组件概览

更多文章请见:http://mobile.51cto.com/abased-346081.htm Android系统承袭了Linux开源操作系统的安全特性,并采用了层次化的方式来保证系统安全,本文将详细介绍Android层次化安全架构及其核...

samsunglinux
07/02
0
0
短信发送--短信的发送流程(framework)

短信的发送流程(framework) 一、主要文件 /packages/apps/Mms/com/android/mm/transaction/SmsSingleRecipientSender /framework/base/telephony/java/com/android/internal/telephony/ISm......

陈wei
2013/02/18
0
0
android广播和短信广播详解----使用广播接收者窃听短信

当系统收到短信时,会发出一个action名称为android.provier.Telephony.SMS_RECEIVED的广播Intent,该Intent存放了接收到的短信内容,使用名称 “pdus”即可从Intent中获取短信内容。 pdus是一...

程序袁_绪龙
2014/09/28
0
0
Android DDMS如何使用?

DDMS 的全称是Dalvik Debug MonitorService,它为我们提供例如:为测试设备截屏,针对特定的进程查看正在运行的线程以及堆信息、Logcat、广播状态信息、模拟电话呼叫、接收SMS、虚拟地理坐标...

Kevin_Gan
2010/07/07
0
0
Android QuickContactBadge联系人快捷标识

public classQuickContactBadgeextends ImageViewimplements View.OnClickListenerjava.lang.Object↳ android.view.View↳ android.widget.ImageView↳ android.widget.QuickContactBadge a......

amigos_wu
2012/05/27
0
0
《Android深入透析》之广播(Broadcast)

概述 在android中,Broadcast作为四大组件之一,被广泛的应用在android程序之间的数据传递。举一个大家都比较熟悉的例子来说明。在车上的时候大家都有收听广播的习惯,广播电台通过发送不同频...

朵朵和糖糖
2014/11/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

TensorFlow 线性分类

构造直线 z = 2 * x - 3 * y + 4 x0*w0+x1*w1+b=0 x1=-x0* w0/w1-b/w1 斜率 k= -w0/w1 截距 -b/w1 随机生成数据,加入一定的偏差,用直线将二维平面分为两部分 使用线性模型拟合参数 损失函数...

阿豪boy
5分钟前
0
0
翻译冒泡排序测试

翻译一个冒泡排序: var a = [1,3,2,4,6,5];var f = 0;var n = a.length ;for( var i =1; i<= n; i++) { for( var j = n-1 ; j >= i; j --) { if(a[j] < a[j+1]) { ......

钟元OSS
6分钟前
0
0
maven父、子级版本号同时修改

命令: mvn versions:set -DnewVersion=0.0.2-SNAPSHOT

沉默的懒猫
8分钟前
0
0
Spring boot中的异常处理之注解响应

Controller层 return patientRepository.findById(id) .orElseThrow(() -> new NotFoundException(String.format("Patient %d not found", id))); Exception类 @ResponseS......

亚林瓜子
9分钟前
0
0
webpack文档翻译_001

概念 webpack是一个为现代JavaScript应用的打包工具(a static module bundler)。 当webpack处理应用时,在其内部,会生成一个依赖图(dependency graph),这个依赖图可以映射到项目里的每一个...

DennisHill
9分钟前
5
0
vim 行首/行尾 批量操作

批量插入 行首插入 :%s/^/your_word/ 行尾插入:%s/$/your_word/ 按键操作 注释:ctrl+v 进入列编辑模式,向下或向上移动光标,把需要注释的行的开头标记起来,然后按大写的I(shift + i),再插入...

温子寒
10分钟前
0
0
Java语言学习(十二):多线程

Java中给多线程编程提供了内置的支持,多线程是多任务的一种特别形式,它使用了更小的资源开销。这里需要知道两个术语及其关系:进程和线程。 进程:进程是系统进行资源分配和调度的一个独立...

海岸线的曙光
16分钟前
0
0
mysql源码阅读相关文章

https://www.jianshu.com/p/e739afb8fe31

writeademo
29分钟前
0
0
CentOS7 安装MySQL8

1. 从官网拿到本地YUM源的安装包,并安装本地YUM源 2. 通过`yum install -y`命令进行MySQL的安装 3. 启动服务,并配置开机自启 4. 获取初始化密码,登录MySQL 5. 修改密码策略,然后自行设置roo...

小致dad
35分钟前
0
0
史上最简单的 IntelliJ IDEA 教程

我不是作者,我只是内容的搬运工。 传送门

颖辉小居
37分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部