在上一次的学习中,我们读取了手机联系人并将其显示在短信界面上,而接下来,我们将开始读取手机短信了,下面先来看一下最终运行效果图吧。

首先看一下手机短信数据库,访问路径是:/data/data/com.android.providers.telephony/databases/mmssms.db,用SQLiteExpertPers打开后可以看到数据库中的表,下面我们来看一下其中的sms表,threads表和canonical_addresses表。
1.sms表:
thread_id:与threads表的_id相对应
address:短信会话人号码
body:短信内容
person:通过SQLiteExpert工具查看,发现无论是否是联系人该列都为null
contact_name:通过SQLiteExpert工具查看,结果为:号码+空格+联系人名称(若为联系人)
status:-1表示短信已接受
read:0为未读,1为已读
type:1表示收到的短信,通过SQLiteExpert工具查看此数据库时发出的信息type值为6

2.threads表
recipient_ids:指向canonical_addresses表的_id字段,通过canonical_addresses表的address字段
可获取联系人号码
snippest:最后收到/发出的信息
message_count:该会话的消息数量

3.canonical_addresses表
_id:与thread表的recipient_ids相对应
address:电话号码

相对于上一个版本,这次工程新增了SMSInfo类作为短信数据库表对应的实体类,在适配器类MessageListAdapter 中,定义新方法getSMSInfo()来获取sms表中的短信记录,并在 MainActivity中调用该方法。另外,在实际读取短信记录时,发现之前的页面布局显示有问题,如在短信列表页面,当某条短信内容较长时,应该采用单行显示,超过一行的部分应该被隐藏,因此对主布局文件activity_main.xml和列表项布局文件list_item.xml也做了修改,如下文所示。另外,与读取联系人一样,读取短信同样需要AndroidManifest.xml文件中配置手机短信读取权限,在文件中增加如下声明:
       <uses-permission android:name="android.permission.READ_SMS"/>
在MessageListAdapter中进行查询时,使用了query方法,我们来看一下这个方法的用法中各参数含义。
     query(Uri uri,String[] project,String selection,String selectionArgs,String sortOrder):
              uri:要读取数据对应的Uri
              projection:需要读取的字段
              selection:数据检索的条件
              selectionArgs:数据检索条件的参数
              sortOrder:对查询结果排序所依据的字段
最后给出程序代码如下:

1.MainActivity.java

<span style="font-size:14px;">package com.example.mymessageproject;import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ListView;public class MainActivity extends Activity {private ListView messageListView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);messageListView = (ListView)this.findViewById(R.id.messageListView);    MessageListAdapter adapter = new MessageListAdapter(this);//获取短信记录adapter.getSMSInfo();        messageListView.setAdapter(adapter);//实时通知数据已更新adapter.notifyDataSetChanged();}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}
}</span>

2.MessageListAdapter.java

package com.example.mymessageproject;import java.io.InputStream;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;public class MessageListAdapter extends BaseAdapter {private LayoutInflater mInflater;private Context mContext = null;/*** 可读取所有的短信的Uri*/public static final String SMS_URI_ALL = "content://sms/";private static final String MesTAG = "Reading Messages";private static final String ThreadTAG = "Reading from Thread Table";private static final String GetPhoneNumberTAG = "Getting phone number";private static final String GetContactByPhoneTAG = "Getting contact by phone number";//存储所有短信信息的列表List<SMSInfo> infos = new ArrayList<SMSInfo>();//MessageListAdapter初始化构造方法public MessageListAdapter(Context context) {mContext = context;mInflater = LayoutInflater.from(mContext);}/*获取手机中的信息,并将其存入信息列表infos中*/public void getSMSInfo() {Uri uri = Uri.parse(SMS_URI_ALL);        Cursor messageCursor = null;ContentResolver resolver = null;try{/**获取短信的各种信息 ,短信数据库sms表结构如下:_id:短信序号,如100  thread_id:对话的序号,如100,与同一个手机号互发的短信,其序号是相同的              address:发件人地址,即手机号,如+8613811810000                            date:日期,long型,如1256539465022,可以对日期显示格式进行设置                        read:是否阅读0为未读              status:短信状态-1表示短信已被接收              type:短信类型1表示接收到的短信              body:短信具体内容              service_center:短信服务中心号码编号,如+8613800755500*/resolver = mContext.getContentResolver();String[] projection = new String[] {"_id", "address","body","date", "type"};uri = Uri.parse(SMS_URI_ALL);/** query(Uri uri,String[] project,String selection,*             String selectionArgs,String sortOrder)方法各参数含义* uri:要读取数据对应的Uri* projection:需要读取的字段* selection:数据检索的条件* selectionArgs:数据检索条件的参数* sortOrder:对查询结果排序所依据的字段* */messageCursor = resolver.query(uri, projection, null, null, "date desc");if (messageCursor == null) {return;}    if (messageCursor.getCount() == 0){messageCursor.close();messageCursor = null;return;}int phoneNumberColumn = messageCursor.getColumnIndex("address");int smsbodyColumn = messageCursor.getColumnIndex("body");int dateColumn = messageCursor.getColumnIndex("date");int typeColumn = messageCursor.getColumnIndex("type");if (messageCursor != null) {while (messageCursor.moveToNext()) {//设置日期显示格式SimpleDateFormat dateFormat = new SimpleDateFormat(  "yyyy-MM-dd");  Date date = new Date(Long.parseLong(messageCursor.getString(dateColumn)));   SMSInfo smsinfo = new SMSInfo();//此处contactMes为电话号码smsinfo.setContactMes(messageCursor.getString(phoneNumberColumn));smsinfo.setDate(dateFormat.format(date));smsinfo.setSmsbody(messageCursor.getString(smsbodyColumn));smsinfo.setType(messageCursor.getString(typeColumn));infos.add(smsinfo);}}messageCursor.close();}catch(Exception e){Log.e(MesTAG,"E:" + e.toString());}finally{if (messageCursor != null){messageCursor.close();messageCursor = null;}}}public Object getItem(int arg0) {// TODO Auto-generated method stubreturn infos.get(arg0);}public long getItemId(int position) {// TODO Auto-generated method stubreturn position;}public int getCount() {// TODO Auto-generated method stub//return contactDataList.size();return infos.size();}public View getView(int position, View convertView,android.view.ViewGroup parent) {            MessageHolder messageHolder = null;//判断convertView是否已创建,若已存在则不必重新创建新视图,节省系统资源if (convertView == null) {// 和item_custom.xml脚本关联convertView = mInflater.inflate(R.layout.list_item, null);messageHolder = new MessageHolder();//加载控件到信息载体中messageHolder.setIvImage((ImageView) convertView.findViewById(R.id.contact_image));messageHolder.setTvTitle((TextView) convertView.findViewById(R.id.titleTextView));messageHolder.setTvDesc((TextView) convertView.findViewById(R.id.descTextView));messageHolder.setTvCount((TextView) convertView.findViewById(R.id.countTextView));messageHolder.setTvTime((TextView) convertView.findViewById(R.id.timeTextView));//将联系人信息载体Holder放入convertView视图convertView.setTag(messageHolder);}else{//从convertView视图取出联系人信息载体HoldermessageHolder = (MessageHolder)convertView.getTag();            }// 通过短信Holder设置list_item中4个TextView的文本与联系人头像    //绘制短信联系人信息,内容为其号码messageHolder.getTvTitle().setText(infos.get(position).getContactMes());//绘制信息内容messageHolder.getTvDesc().setText(infos.get(position).getSmsbody());//此处显示的是当前所有短信数量messageHolder.getTvCount().setText(""+infos.size());//绘制时间messageHolder.getTvTime().setText(infos.get(position).getDate());// 设置显示在每条短信左边的图片messageHolder.getIvImage().setBackgroundResource(R.drawable.ic_launcher);return convertView;}
}

3.SMSInfo.java

package com.example.mymessageproject;import android.graphics.Bitmap;public class SMSInfo {/*** 短信内容*/private String smsbody;/**** 发送短信的日期和时间*/private String date;/*** 短信类型1是接收到的,通过SQLiteExpertPers查看发出信息类型为6*/private String type;/*** 与同一个联系人的会话包含的消息数*/private String messageCout;             /*** 会话人的信息,属于联系人则为名称,否则为其号码*/private String contactMes;/*** 该会话对应的联系人头像*/private Bitmap contactPhoto;public String getContactMes() {return contactMes;}public void setContactMes(String contactMes) {this.contactMes = contactMes;}public Bitmap getContactPhoto() {return contactPhoto;}public void setContactPhoto(Bitmap contactPhoto) {this.contactPhoto = contactPhoto;}public String getMessageCout() {return messageCout;}public void setMessageCout(String messageCout) {this.messageCout = messageCout;}public String getSmsbody() {return smsbody;}public void setSmsbody(String smsbody) {this.smsbody = smsbody;}public String getDate() {return date;}public void setDate(String date) {this.date = date;}public String getType() {return type;}public void setType(String type) {this.type = type;}}

4.activity_main.xml

<span style="font-size:14px;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity" ><ListViewandroid:id="@+id/messageListView"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_alignParentTop="true"android:layout_marginBottom="50dip"></ListView><Buttonandroid:id="@+id/newMessageButton"android:layout_width="fill_parent"android:layout_height="50dip"android:layout_alignLeft="@+id/messageListView"android:layout_alignParentBottom="true"android:text="新信息" /></RelativeLayout>5.list_item.xml<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="fill_parent"  android:layout_height="wrap_content"android:layout_marginTop="10dip"android:layout_marginBottom="10dip"android:layout_marginLeft="10dip"android:layout_marginRight="10dip">       <ImageView android:id="@+id/contact_image"  android:layout_width="60dip"  android:layout_height="60dip"android:layout_alignParentLeft="true"  >  </ImageView>  <TextView android:id="@+id/titleTextView"  android:singleLine="true"android:layout_width="160dip"  android:layout_height="wrap_content"  android:layout_alignParentTop="true"android:layout_toRightOf="@id/contact_image"  android:textSize="20sp"  android:layout_marginBottom="10dip"/>  <TextView android:id="@+id/descTextView"  android:singleLine="true"android:layout_width="180dip"  android:layout_height="wrap_content"android:layout_marginBottom="10dip"  android:layout_toRightOf="@id/contact_image"  android:layout_below="@id/titleTextView"  android:textSize="20sp"  />    <!-- android:layout_alignParentBottom="true" -->     <TextView android:id="@+id/countTextView"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignParentRight="true"android:textSize="20sp"  android:layout_marginRight="10dip"/><TextView android:id="@+id/timeTextView"  android:singleLine="true"android:layout_width="wrap_content"android:layout_height="wrap_content"  android:layout_alignParentRight="true"  android:layout_alignBottom="@id/descTextView"android:textSize="15sp"android:layout_marginRight="10dip"  /></RelativeLayout> </span> 

好了,今天就到到这里吧,在上一篇和这一篇文章中,我们分别读取了手机联系人和手机短信,在下一次,将开始联结查询两个数据库,进一步完善在短信会话主界面联系人头像等信息的展示。

参考文章链接:http://www.cnblogs.com/kakafra/archive/2012/09/28/2707790.html

基于Android的短信应用开发(三)——读取手机短信相关推荐

  1. 小米8系统推送服务器,小米8推送基于Android 10的MIUI 11开发版

    据IT之家网友反馈,小米8开始推送基于Android 10的MIUI 11开发版.本次更新包大小2.1G,除了升级底层为Android 10之外,还带来了谷歌10月安全更新. 更新日志: MIUI 1 ...

  2. interlib android客户端开发,基于Android移动图书馆设计与开发.doc

    基于Android移动图书馆设计与开发 基于Android移动图书馆设计与开发 [摘 要]随着移动 技术的发展,图书馆数字化的资源已不局限于在电脑上进行展示,手机已成为用户浏览图书 馆数字化资源的重要 ...

  3. 开发一个发送手机短信的计算机软件

    开发一个发送手机短信的计算机软件 很久以前就有这个想法了,无奈时间有限,资料不足,一直没有成功.昨天突然意念再生,没想到还真搞成功了.接下来我将对这方面的技术做一个总结,并详细介绍我使用的方法细节.我 ...

  4. 网页短信平台开发为什么要用短信服务程序

    网页短信平台开发为什么要用短信服务程序 一:概述 有人会问开发网页版的平台或者系统直接写BS就可以了,为什么还要写服务程序.其实不用写服务程序也可以但是大量的逻辑操作或者是数据操作的话直接写到网页上会 ...

  5. android记事本的设计报告,基于android记事本的设计与开发开题报告.doc

    基于android记事本的设计与开发开题报告.doc 太 原 科 技 大 学 华 科 学 院毕业设计开题报告学 生 姓 名学 号学 院.系 专 业论 文 题 目基于android的记事本的开发与设计指 ...

  6. 基于Android小巫新闻客户端开发---显示新闻详细内容UI设计

    基于Android小巫新闻客户端开发---显示新闻详细内容UI设计 2013年2月27日,天气潮湿!!! 距上一次写的主界面业务逻辑实现,已经过来11天,小巫觉得拖得太久了,所以决定尽量把所有的内容介 ...

  7. 基于Android + Web+ MySQL设计和开发微博应用

    基于Android + Web+ MySQL设计和开发微博应用 实践内容要求 客户端效果图 源码分享 微博应用系统设计 系统功能设计 关键问题设计 实践内容要求 ①用Android开发微博客户端: ② ...

  8. android备忘录开题报告,基于android记事本的设计与开发开题报告.doc

    基于android记事本的设计与开发开题报告 太 原 科 技 大 学 华 科 学 院 毕业设计开题报告 学 生 姓 名:学 号:学 院.系: 专 业:论 文 题 目:基于android的记事本的开发与 ...

  9. 短视频APP开发主要依赖于短视频SDK架构设计

    短视频 SDK 架构中主要做的一些事情,这其中最重要的就是短视频 SDK 的架构设计,包括架构设计理念.架构图.整体数据流程.模块架构设计等.今天小编就简单介绍一下短视频APP开发中,选择什么样的厂家 ...

最新文章

  1. 附加 集合数据_浩辰3D软件新手教程:三维建模设计中如何重用CAD模型数据?
  2. [Tool] 使用CodeMaid自動程式排版 - 摘自网络
  3. 使用游标显示销售报表_协助报表开发之 MongoDB join mysql
  4. ABAP workbench API的使用方法
  5. jpa 实体映射视图_JPA教程:实体映射-第2部分
  6. swwht(canvas).demo
  7. matlab产生er随机图,ER随机图模型
  8. 安装纯净版windows系统,win10企业版LTSC
  9. java对接modbus rtu协议设备
  10. TTL电平信号和RS232信号波形对比
  11. 高数 07.03 全微分
  12. 如何部署一个属于自己的网站
  13. Node.JS实战57:给图片加水印。
  14. Java自动拆装箱总结
  15. 【论文阅读笔记】faster rcnn 代码阅读细节
  16. 机器健康监测的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  17. 考研数据结构填空题整合_做题版
  18. mysql如何启动_如何重启MySQL,正确启动MySQL
  19. CVPR 2020 Tutorial How to write a good rebuttal(如何写一篇好反驳)概要总结
  20. 你们中国人真TM假,微信居然能撤回…

热门文章

  1. 计算机cdef盘无法显示,科技常识:如何解决电脑CDEF盘都打不开出现ldq
  2. 最新SWAPIDC本地后台登陆 – 替换包
  3. 2021-2027全球与中国高速特种电缆市场现状及未来发展趋势
  4. 【Android底层学习总结】1. 驱动开发基础
  5. VulnHub渗透测试实战靶场 - Odin:1
  6. Vector BLF格式转ASC格式软件 QT+C++编写
  7. js实例化以及constructor探究
  8. 好用的Maven仓库推荐
  9. vue创建项目报错command not found:create-webpack
  10. C语言malloc函数的功能及用法