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

弹出对话框.apk安装包 可直接点击安装的安卓程序,能够实现对话框的弹出,实现单选,多选以及登录验证 立即下载
讨论一下Android平台下如何调用系统方法发送短信、接收短信、系统的短信库相关的问题。进入正题,我们先使用Eclipse工具模拟给自己的模拟器发送一条短信。在Eclipse下打开DDMS


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




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

2.gif 



系统的短信库存在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  表示 消息的内容

4.gif (7.61 KB, 下载次数: 124)

下载附件  保存到相册

2011-9-3 01:25 上传



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

5.gif (8.23 KB, 下载次数: 131)

下载附件  保存到相册

2011-9-3 01:25 上传


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

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

6.gif (28.53 KB, 下载次数: 115)

下载附件  保存到相册

2011-9-3 01:25 上传


这么看来如果须要短信库中的数据就去访问数据库中的这两张表,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.         // create the sentIntent parameter
  5.         Intent sentIntent = new Intent(SENT_SMS_ACTION);
  6.         PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sentIntent,
  7.                 0);

  8.         // create the deilverIntent parameter
  9.         Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);
  10.         PendingIntent deliverPI = PendingIntent.getBroadcast(this, 0,
  11.                 deliverIntent, 0);

  12.         //如果短信内容超过70个字符 将这条短信拆成多条短信发送出去
  13.         if (message.length() > 70) {
  14.             ArrayList<String> msgs = sms.divideMessage(message);
  15.             for (String msg : msgs) {
  16.                 sms.sendTextMessage(phoneNumber, null, msg, sentPI, deliverPI);
  17.             }
  18.         } else {
  19.             sms.sendTextMessage(phoneNumber, null, message, sentPI, deliverPI);
  20.         }
  21.     }
复制代码
注册 接收成功 或者发送成功的广播
  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.         @Override
  3.         public void onReceive(Context context, Intent intent) {
  4.             //判断短信是否发送成功
  5.             switch (getResultCode()) {
  6.             case Activity.RESULT_OK:
  7.                 Toast.makeText(context, "短信发送成功", Toast.LENGTH_SHORT).show();
  8.                 break;
  9.             default:
  10.                 Toast.makeText(mContext, "发送失败", Toast.LENGTH_LONG).show();
  11.                 break;
  12.             }
  13.         }
  14.     };
  15.    
  16.    
  17.     private BroadcastReceiver receiver = new BroadcastReceiver() {

  18.         @Override
  19.         public void onReceive(Context context, Intent intent) {
  20.             //表示对方成功收到短信
  21.             Toast.makeText(mContext, "对方接收成功",Toast.LENGTH_LONG).show();
  22.         }
  23.     };
复制代码
下面给出这个小例子的完整代码
  1. import java.util.ArrayList;

  2. import android.app.Activity;
  3. import android.app.PendingIntent;
  4. import android.content.BroadcastReceiver;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.IntentFilter;
  8. import android.os.Bundle;
  9. import android.telephony.SmsManager;
  10. import android.text.TextUtils;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.widget.Button;
  14. import android.widget.EditText;
  15. import android.widget.Toast;

  16. public class ContactsActivity extends Activity {


  17.     /**发送按钮**/
  18.     Button button = null;
  19.    
  20.     /**收件人电话**/
  21.     EditText mNumber = null;
  22.    
  23.     /**编辑信息**/
  24.     EditText mMessage = null;
  25.    
  26.     /**发送与接收的广播**/
  27.     String SENT_SMS_ACTION = "SENT_SMS_ACTION";
  28.     String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";

  29.    
  30.    
  31.     Context mContext = null;
  32.     @Override
  33.     public void onCreate(Bundle savedInstanceState) {
  34.         super.onCreate(savedInstanceState);
  35.         setContentView(R.layout.message);

  36.         button = (Button) findViewById(R.id.button);
  37.         mNumber = (EditText) findViewById(R.id.number);
  38.         mMessage = (EditText) findViewById(R.id.message);

  39.         mContext = this;
  40.         button.setOnClickListener(new OnClickListener() {

  41.             @Override
  42.             public void onClick(View view) {

  43.                 /** 拿到输入的手机号码 **/
  44.                 String number = mNumber.getText().toString();
  45.                 /** 拿到输入的短信内容 **/
  46.                 String text = mMessage.getText().toString();

  47.                 /** 手机号码 与输入内容 必需不为空 **/
  48.                 if (!TextUtils.isEmpty(number) && !TextUtils.isEmpty(text)) {
  49.                     sendSMS(number, text);
  50.                 }
  51.             }
  52.         });

  53.        
  54.         // 注册广播 发送消息
  55.         registerReceiver(sendMessage, new IntentFilter(SENT_SMS_ACTION));
  56.         registerReceiver(receiver, new IntentFilter(DELIVERED_SMS_ACTION));

  57.     }
  58.    
  59.     private BroadcastReceiver sendMessage = new BroadcastReceiver() {

  60.         @Override
  61.         public void onReceive(Context context, Intent intent) {
  62.             //判断短信是否发送成功
  63.             switch (getResultCode()) {
  64.             case Activity.RESULT_OK:
  65.                 Toast.makeText(context, "短信发送成功", Toast.LENGTH_SHORT).show();
  66.                 break;
  67.             default:
  68.                 Toast.makeText(mContext, "发送失败", Toast.LENGTH_LONG).show();
  69.                 break;
  70.             }
  71.         }
  72.     };
  73.    
  74.    
  75.     private BroadcastReceiver receiver = new BroadcastReceiver() {

  76.         @Override
  77.         public void onReceive(Context context, Intent intent) {
  78.             //表示对方成功收到短信
  79.             Toast.makeText(mContext, "对方接收成功",Toast.LENGTH_LONG).show();
  80.         }
  81.     };
  82.    
  83.         /**
  84.          * 参数说明
  85.          * destinationAddress:收信人的手机号码
  86.          * scAddress:发信人的手机号码
  87.          * text:发送信息的内容
  88.          * sentIntent:发送是否成功的回执,用于监听短信是否发送成功。
  89.          * DeliveryIntent:接收是否成功的回执,用于监听短信对方是否接收成功。
  90.          */
  91.     private void sendSMS(String phoneNumber, String message) {
  92.         // ---sends an SMS message to another device---
  93.         SmsManager sms = SmsManager.getDefault();

  94.         // create the sentIntent parameter
  95.         Intent sentIntent = new Intent(SENT_SMS_ACTION);
  96.         PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sentIntent,
  97.                 0);

  98.         // create the deilverIntent parameter
  99.         Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);
  100.         PendingIntent deliverPI = PendingIntent.getBroadcast(this, 0,
  101.                 deliverIntent, 0);

  102.         //如果短信内容超过70个字符 将这条短信拆成多条短信发送出去
  103.         if (message.length() > 70) {
  104.             ArrayList<String> msgs = sms.divideMessage(message);
  105.             for (String msg : msgs) {
  106.                 sms.sendTextMessage(phoneNumber, null, msg, sentPI, deliverPI);
  107.             }
  108.         } else {
  109.             sms.sendTextMessage(phoneNumber, null, message, sentPI, deliverPI);
  110.         }
  111.     }

  112. }
复制代码
一定要在AndroidManifest.xml中添加发送短信的权限噢。
  1.     <!--取得发短信的权限 -->
  2.     <uses-permission android:name="android.permission.SEND_SMS" />
复制代码
发送完消息后打开手机的发信箱发现没有看到刚才发的消息,这是为什么呢? 是这样的。调用sendTextMessage 确实是发送消息 ,但是系统的短信库中没有这条消息 所以就看不到了。如果想要在系统的短信库中看到消息就必需把这条消息插到系统的短信库。


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

  2.             @Override
  3.             public void onClick(View view) {

  4.                 /** 拿到输入的手机号码 **/
  5.                 String number = mNumber.getText().toString();
  6.                 /** 拿到输入的短信内容 **/
  7.                 String text = mMessage.getText().toString();

  8.                 /** 手机号码 与输入内容 必需不为空 **/
  9.                 if (!TextUtils.isEmpty(number) && !TextUtils.isEmpty(text)) {
  10.                     sendSMS(number, text);
  11.                
  12.                     /**将发送的短信插入数据库**/
  13.                     ContentValues values = new ContentValues();
  14.                     //发送时间
  15.                     values.put("date", System.currentTimeMillis());
  16.                     //阅读状态
  17.                     values.put("read", 0);
  18.                     //1为收 2为发
  19.                     values.put("type", 2);
  20.                     //送达号码
  21.                     values.put("address", number);
  22.                     //送达内容
  23.                     values.put("body", text);
  24.                     //插入短信库
  25.                     getContentResolver().insert(Uri.parse("content://sms"),values);

  26.                 }
  27.             }
  28.         });
复制代码
还是一定要在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" />
复制代码
规矩每篇文章都会附带源代码,最后如果你还是觉得我写的不够详细 看的不够爽 不要紧我把源代码的下载地址贴出来 欢迎大家一起讨论学习

第三十讲 给联系人发送短信.rar(124.34 KB, 下载次数: 1380)


http://www.apkbus.com/android-13446-1-1.html

BMS菊花链芯片怎么选?一张表对比ADI、TI、NXP五大厂家的隔离通信方案 本文深入对比了ADI、TI、NXP等五大厂商的BMS菊花链芯片隔离通信方案,涵盖技术演进、核心参数和场景化选型策略。通过实测数据和开发经验分享,帮助工程师在新能源汽车和储能系统中选择最优方案,提升通信可靠性和成本效益。 阅读详情

相关推荐

继电器的选型规范

触点是继电器中最重要的结构件,触点的使用寿命受触点材料、触点上的电压及电流值(特别是接通时及断开时的电压、电流波形)、负载种类、切换频率、环境情况、接触形式、触点回跳现象等的影响,触点失效多以触点的材料转移、粘连、异常消耗、接触电阻增大等故障现象出现,使用时需要注意。为了稳定工作, DC 型继电器的线圈两端所加电压推荐使用波纹变化率小于±5%的线圈额定电压,否则继电器会工作不稳定,引起触点的粘接或异常损耗,特别是在继电器的驱动电路上连接有电动机、螺线管、变压器等器件时,这种情况更为明显。

qq_43416206的博客 1878

android 静默发短信_Android 发短信功能

packagecom.sms.ui;importjava.util.List;importandroid.app.Activity;importandroid.os.Bundle;importandroid.telephony.SmsManager;importandroid.view.View;importandroid.view.View.OnClickListener;importandro...

weixin_40005795的博客 555

网络可视化工具netron详细安装流程

netron安装目录1.netron 简介2.不同操作系统下的安装使用方式2.1 在线版本:只要有浏览器就可以2.2 不同操作系统安装使用3.netron支持的网络框架4.netron测试演示 1.netron 简介 在实际的项目中,经过会遇到各种网络模型,需要我们快速去了解网络结构。如果单纯的去看模型文件,脑海中很难直观的浮现网络的架构。 这时,就可以使用netron可视化工具,可以清晰的看到每一层的输入输出,网络总体的架构,而且支持各种不同网络框架,简单好用。 2.不同操作系统下的安装使用方式 2.1

江南研习社 12万+

Android软件开发之发送短信与系统短信库解析(三十)

Android软件开发之发送短信与系统短信库解析雨松MOMO原创文章如转载,请注明:转载至我的独立域名博客雨松MOMO程序研究院,原文地址:http://www.xuanyusong.com/archives/182今天我和同学们讨论一下Android平台下如何调用系统方法发送短信、接收短信、系统的短信库相关的问题。进入正题,我们先使用Eclipse工具模拟给自己的模拟器发送一条短信。在Eclip

雨松MOMO的程序世界专栏 2万+

【STM32】433MHz OOK信号软解码实战:从EV1527协议到嵌入式实现

本文详细介绍了基于STM32微控制器实现433MHz OOK信号软解码的完整实战过程。文章从EV1527协议解析入手,重点阐述了利用STM32的GPIO和定时器进行信号采样、脉宽还原、同步头识别以及数据位判决的核心算法,并提供了对抗无线干扰的容错优化策略,帮助开发者深入理解并掌握低成本无线通信的嵌入式实现方案。

weixin_29299807的博客 783

【图像大模型】RIFE实战:如何通过中间流估计实现4K视频的实时插帧优化

本文深入解析了基于深度学习的RIFE视频插帧算法,重点探讨其核心的中间流估计技术如何实现高效精准的帧生成。通过实战教程,详细介绍了针对4K视频的实时处理优化方案,包括环境配置、参数调优及性能瓶颈分析,帮助用户利用消费级显卡将低帧率视频转化为流畅的高帧率体验。

weixin_29093017的博客 455
上一篇: android 中调用接口发送短信
下一篇: Android的Intent的Action大全
focusjava
博客等级 码龄14年 127粉丝 528原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值