`

Android软件开发之发送短信与系统短信库解析

 
阅读更多
雨松MOMO原创文章如转载,请注明:转载自雨松MOMO的博客原文地址:http://blog.csdn.net/xys289187120/article/details/6740933












今天我和同学们讨论一下Android平台下如何调用系统方法发送短信、接收短信、系统的短信库相关的问题。进入正题,我们先使用Eclipse工具模拟给自己的模拟器发送一条短信。在Eclipse下打开DDMS


Incoming number: 这里须要填写的是发件人的手机号码,这里只能输入数字否则会无法发送。
Message: 这里为发送的内容
send: 上面两项都填写完毕点击发送键可以给模拟器发送短信。







点击发送后,模拟器中就可以看到自己收到了一条消息 发件人的号码为123456 发送内容为hello。收到短信后会将这条信息写入系统的短信库,下面我们分析分析Android系统的短信库的结构。









 

系统的短信库存在data/data/com.android.providers.telephony/databases/mmssms.db 下图蓝框中就是模拟器的短信库,我们将它打开看看里面存的是什么东东。







打开mmssms.db  在打开sms表 因为所有短信数据都储存在这张表上,下面分析一下这张表的字段。
_id 不用说了吧,标示它的唯一性
thread_id :这个字段很重要,同一个会话中他们的thread_id是一样的,也就是说通过thread_id就可以知道A与B在聊天 还是 A与C在聊天
date :这条消息发送或接收的时间
read:  0 表示未读 1表示已读
type : 1表示接收 2 表示发出
body  表示 消息的内容





我给12345回一条消息我们会看的更清楚这些节点的意义。






我们在看看thread_id指向的thread表
上图中可以清晰的看到 收到消息与回复消息的thread_id都为1 ,那么在thread_id这张表中

_id 不用说了吧,标示它的唯一性
date:表示最后接收或者发送消息的时间
message_count:表示发送消息的数量,这里我接收到了一条消息 也回复了一条消息那么它的数量就为2
recipient_ids:联系人ID,指向表 canonical_addresses 里的id。
snippet :最后收到或者发送的消息内容,就是上图body中存的东西







这么看来如果须要短信库中的数据就去访问数据库中的这两张表,sms表 uri 指向的是 "content://mms-sms/" thread表 uri指向的是"content://mms-sms/threadID" 具体访问的方法请看Android游戏开发之数据库SQLite 详细介绍(十七) 这里就不详细的说了。

下面进入本章代码部分的正题,调用系统方法给联系人号码发送消息







    /**
     * 参数说明
     * destinationAddress:收信人的手机号码
     * scAddress:发信人的手机号码
     * text:发送信息的内容
     * sentIntent:发送是否成功的回执,用于监听短信是否发送成功。
     * DeliveryIntent:接收是否成功的回执,用于监听短信对方是否接收成功。
     */

这里我主要说一下最后两个参数, SentIntent 这个intent用于接收这条信息自己发送成功还是自己发送失败, DeliveryIntent这个intent用于对方是否接受成功。 发送成功和接受成功是不一样的,发送只是把消息发到手机移动或联通运行商那里叫发送成功,至于以后怎么处理它不关心,只管发送是否成功。 而接受成功表示接受者是否将这条消息收到。




  1.    private void sendSMS(String phoneNumber, String message) {  
  2. // ---sends an SMS message to another device---   
  3. SmsManager sms = SmsManager.getDefault();  
  4.   
  5. // create the sentIntent parameter   
  6. Intent sentIntent = new Intent(SENT_SMS_ACTION);  
  7. PendingIntent sentPI = PendingIntent.getBroadcast(this0, sentIntent,  
  8.     0);  
  9.   
  10. // create the deilverIntent parameter   
  11. Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);  
  12. PendingIntent deliverPI = PendingIntent.getBroadcast(this0,  
  13.     deliverIntent, 0);  
  14.   
  15. //如果短信内容超过70个字符 将这条短信拆成多条短信发送出去   
  16. if (message.length() > 70) {  
  17.     ArrayList<String> msgs = sms.divideMessage(message);  
  18.     for (String msg : msgs) {  
  19.     sms.sendTextMessage(phoneNumber, null, msg, sentPI, deliverPI);  
  20.     }  
  21. else {  
  22.     sms.sendTextMessage(phoneNumber, null, message, sentPI, deliverPI);  
  23. }  
  24.    }  


注册 接收成功 或者发送成功的广播

  1. // 注册广播 发送消息   
  2. registerReceiver(sendMessage, new IntentFilter(SENT_SMS_ACTION));  
  3. registerReceiver(receiver, new IntentFilter(DELIVERED_SMS_ACTION));  


注册后 在BroadcaseRecevice中可以接收到发送 接收相关的广播


  1.    private BroadcastReceiver sendMessage = new BroadcastReceiver() {  
  2.   
  3. @Override  
  4. public void onReceive(Context context, Intent intent) {  
  5.     //判断短信是否发送成功   
  6.     switch (getResultCode()) {  
  7.     case Activity.RESULT_OK:  
  8.     Toast.makeText(context, "短信发送成功", Toast.LENGTH_SHORT).show();  
  9.     break;  
  10.     default:  
  11.     Toast.makeText(mContext, "发送失败", Toast.LENGTH_LONG).show();  
  12.     break;  
  13.     }  
  14. }  
  15.    };  
  16.      
  17.     
  18.    private BroadcastReceiver receiver = new BroadcastReceiver() {  
  19.   
  20. @Override  
  21. public void onReceive(Context context, Intent intent) {  
  22.     //表示对方成功收到短信   
  23.     Toast.makeText(mContext, "对方接收成功",Toast.LENGTH_LONG).show();  
  24. }  
  25.    };  


下面给出这个小例子的完整代码

  1. import java.util.ArrayList;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.PendingIntent;  
  5. import android.content.BroadcastReceiver;  
  6. import android.content.Context;  
  7. import android.content.Intent;  
  8. import android.content.IntentFilter;  
  9. import android.os.Bundle;  
  10. import android.telephony.SmsManager;  
  11. import android.text.TextUtils;  
  12. import android.view.View;  
  13. import android.view.View.OnClickListener;  
  14. import android.widget.Button;  
  15. import android.widget.EditText;  
  16. import android.widget.Toast;  
  17.   
  18. public class ContactsActivity extends Activity {  
  19.   
  20.   
  21.     /**发送按钮**/  
  22.     Button button = null;  
  23.       
  24.     /**收件人电话**/  
  25.     EditText mNumber = null;  
  26.       
  27.     /**编辑信息**/  
  28.     EditText mMessage = null;  
  29.       
  30.     /**发送与接收的广播**/  
  31.     String SENT_SMS_ACTION = "SENT_SMS_ACTION";  
  32.     String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";  
  33.    
  34.       
  35.       
  36.     Context mContext = null;  
  37.     @Override  
  38.     public void onCreate(Bundle savedInstanceState) {  
  39.     super.onCreate(savedInstanceState);  
  40.     setContentView(R.layout.message);  
  41.   
  42.     button = (Button) findViewById(R.id.button);  
  43.     mNumber = (EditText) findViewById(R.id.number);  
  44.     mMessage = (EditText) findViewById(R.id.message);  
  45.   
  46.     mContext = this;  
  47.     button.setOnClickListener(new OnClickListener() {  
  48.   
  49.         @Override  
  50.         public void onClick(View view) {  
  51.   
  52.         /** 拿到输入的手机号码 **/  
  53.         String number = mNumber.getText().toString();  
  54.         /** 拿到输入的短信内容 **/  
  55.         String text = mMessage.getText().toString();  
  56.   
  57.         /** 手机号码 与输入内容 必需不为空 **/  
  58.         if (!TextUtils.isEmpty(number) && !TextUtils.isEmpty(text)) {  
  59.             sendSMS(number, text);  
  60.         }  
  61.         }  
  62.     });  
  63.   
  64.       
  65.     // 注册广播 发送消息   
  66.     registerReceiver(sendMessage, new IntentFilter(SENT_SMS_ACTION));  
  67.     registerReceiver(receiver, new IntentFilter(DELIVERED_SMS_ACTION));  
  68.   
  69.     }  
  70.       
  71.     private BroadcastReceiver sendMessage = new BroadcastReceiver() {  
  72.   
  73.     @Override  
  74.     public void onReceive(Context context, Intent intent) {  
  75.         //判断短信是否发送成功   
  76.         switch (getResultCode()) {  
  77.         case Activity.RESULT_OK:  
  78.         Toast.makeText(context, "短信发送成功", Toast.LENGTH_SHORT).show();  
  79.         break;  
  80.         default:  
  81.         Toast.makeText(mContext, "发送失败", Toast.LENGTH_LONG).show();  
  82.         break;  
  83.         }  
  84.     }  
  85.     };  
  86.       
  87.      
  88.     private BroadcastReceiver receiver = new BroadcastReceiver() {  
  89.   
  90.     @Override  
  91.     public void onReceive(Context context, Intent intent) {  
  92.         //表示对方成功收到短信   
  93.         Toast.makeText(mContext, "对方接收成功",Toast.LENGTH_LONG).show();  
  94.     }  
  95.     };  
  96.       
  97.     /** 
  98.      * 参数说明 
  99.      * destinationAddress:收信人的手机号码 
  100.      * scAddress:发信人的手机号码  
  101.      * text:发送信息的内容  
  102.      * sentIntent:发送是否成功的回执,用于监听短信是否发送成功。 
  103.      * DeliveryIntent:接收是否成功的回执,用于监听短信对方是否接收成功。 
  104.      */  
  105.     private void sendSMS(String phoneNumber, String message) {  
  106.     // ---sends an SMS message to another device---   
  107.     SmsManager sms = SmsManager.getDefault();  
  108.   
  109.     // create the sentIntent parameter   
  110.     Intent sentIntent = new Intent(SENT_SMS_ACTION);  
  111.     PendingIntent sentPI = PendingIntent.getBroadcast(this0, sentIntent,  
  112.         0);  
  113.   
  114.     // create the deilverIntent parameter   
  115.     Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);  
  116.     PendingIntent deliverPI = PendingIntent.getBroadcast(this0,  
  117.         deliverIntent, 0);  
  118.   
  119.     //如果短信内容超过70个字符 将这条短信拆成多条短信发送出去   
  120.     if (message.length() > 70) {  
  121.         ArrayList<String> msgs = sms.divideMessage(message);  
  122.         for (String msg : msgs) {  
  123.         sms.sendTextMessage(phoneNumber, null, msg, sentPI, deliverPI);  
  124.         }  
  125.     } else {  
  126.         sms.sendTextMessage(phoneNumber, null, message, sentPI, deliverPI);  
  127.     }  
  128.     }  
  129.   
  130. }  

一定要在AndroidManifest.xml中添加发送短信的权限噢。

  1. <!--取得发短信的权限 -->  
  2. <uses-permission android:name="android.permission.SEND_SMS" />  





发送完消息后打开手机的发信箱发现没有看到刚才发的消息,这是为什么呢? 是这样的。调用sendTextMessage 确实是发送消息 ,但是系统的短信库中没有这条消息 所以就看不到了。如果想要在系统的短信库中看到消息就必需把这条消息插到系统的短信库。


下面这段代码在发短信的同时也将短信内容写入系统库,这样在发件箱中就可以看到我们发送的短信了。


  1. button.setOnClickListener(new OnClickListener() {  
  2.   
  3.     @Override  
  4.     public void onClick(View view) {  
  5.   
  6.     /** 拿到输入的手机号码 **/  
  7.     String number = mNumber.getText().toString();  
  8.     /** 拿到输入的短信内容 **/  
  9.     String text = mMessage.getText().toString();  
  10.   
  11.     /** 手机号码 与输入内容 必需不为空 **/  
  12.     if (!TextUtils.isEmpty(number) && !TextUtils.isEmpty(text)) {  
  13.         sendSMS(number, text);  
  14.       
  15.         /**将发送的短信插入数据库**/  
  16.         ContentValues values = new ContentValues();  
  17.         //发送时间   
  18.         values.put("date", System.currentTimeMillis());  
  19.         //阅读状态   
  20.         values.put("read"0);  
  21.         //1为收 2为发   
  22.         values.put("type"2);  
  23.         //送达号码   
  24.         values.put("address", number);  
  25.         //送达内容   
  26.         values.put("body", text);  
  27.         //插入短信库   
  28.         getContentResolver().insert(Uri.parse("content://sms"),values);  
  29.   
  30.     }  
  31.     }  
  32. });  


还是一定要在AndroidManifest.xml中添加相关的权限噢。

  1.    <!--  发送消息-->  
  2. <uses-permission android:name="android.permission.SEND_SMS"/>  
  3. <!--  阅读消息-->  
  4. <uses-permission android:name="android.permission.READ_SMS"/>  
  5. <!--  写入消息-->  
  6. <uses-permission android:name="android.permission.WRITE_SMS" />  
  7. <!-- 接收消息 -->  
  8. <uses-permission android:name="android.permission.RECEIVE_SMS" />  



分享到:
评论

相关推荐

    Google Android SDK开发范例大全(第3版) 1/5

    分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言,熟悉面向对象技术与Eclipse、...

    Google Android SDK开发范例大全(第3版) 4/5

    分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言,熟悉面向对象技术与Eclipse、...

    Google Android SDK开发范例大全(第3版) 3/5

    分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言,熟悉面向对象技术与Eclipse、...

    Google Android SDK开发范例大全(完整版)

    余志龙,来自于手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及J2EE、JSP、Servlet、JavaBeans、PHP、C#等程序语言,熟悉面向对象技术与Eclipse...

    深入理解Android:卷I--详细书签版

     Android系统开发工程师常常需要深入理解系统的运转过程,而本书所涉及的内容可能正是他们在工作和学习中最想了解的。那些对具体模块(如Audio系统和Surface系统)感兴趣的读者 也可以直接阅读相关章节的内容。 ...

    传智播客的android开发源代码

    04_开发与运行(卸载)第一个ANDROID应用.avi 所在项目:Hello 06_电话拔号器.avi 所在项目:phone 08_短信发送器.avi 所在项目:sms 09_深入了解各种布局技术.avi 所在项目:sms & FrameLayout 10_对应用进行单元...

    传智播客Android视频教程-课程源码.rar

    项目名称 Android手机视频客户端:本系统专为视频网站与电视媒体而开发的手机视频客户端,通过该软件,手机用户可以在线观看视频,在线播放MP3,上传视频,下载视频,视频搜索,视频共享、了解最新最热视频资讯。...

    黎活明android教程的全程PPT

    4&gt; 开发与运行(卸载)第一个ANDROID应用 5&gt; 项目的目录结构 6&gt; 项目清单文件分析 7&gt; 分析第一个ANDROID应用的启动过程 8&gt; 电话拔打 9&gt; 查看手机模拟器往控制台输出的日志信息 10&gt; 如何部署应用到真实手机 11&gt; ...

    8天快速掌握Android教程源码

    04_开发与运行(卸载)第一个ANDROID应用.avi 所在项目:Hello 06_电话拔号器.avi 所在项目:phone 08_短信发送器.avi 所在项目:sms 09_深入了解各种布局技术.avi 所在项目:sms & FrameLayout 10_对应用进行单元...

    android知识大总结【邯院】

    第三章 电话拨号器和发送短信小程序 12 第四章 日志输出和单元测试 17 第五章 数据的存储与访问 19 第六章 SD卡的存取和XML读取 24 第七章 SharedPreferences进行数据存储 38 第八章 SQLITE数据库 42 第九章 ...

    Java资源包01

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    java开源包10

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    JAVA上百实例源码以及开源项目源代码

     用JAVA开发的一个小型的目录监视系统,系统会每5秒自动扫描一次需要监视的目录,可以用来监视目录中文件大小及文件增减数目的变化。 Java日期选择控件完整源代码 14个目标文件 内容索引:JAVA源码,系统相关,日历,...

    java开源包1

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    JAVA上百实例源码以及开源项目

    此时此景,笔者只专注Android、Iphone等移动平台开发,看着这些源码心中有万分感慨,写此文章纪念那时那景! Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这...

    java开源包11

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

Global site tag (gtag.js) - Google Analytics