基于Android的短信应用开发(五)——读取显示会话信息记录
2014-11-08 21:19
881 查看
在上一次,我们读取显示了短信会话列表,接下来,要继续进行的工作就是点击每个短信会话后,显示该会话包含的所有信息记录,我们还是先来看一下运行效果吧,左图为短信会话列表,右图为点击其中第二个会话之后看到的该会话下的短信记录,蓝色背景的为发出的短信,灰色背景的为收到的短信。
为了显示各个会话下所有的短信记录,需要取得短信会话的会话id,即sms表中的字段“thread_id”,而在上一篇文章中,我们已经在MessageListAdapter的getMessageSessions()方法中取得了每个短信会话的id,因此,我们还是先回去看一下吧,下面在getMessageSessions()中,红色代码部分执行了从threads表获取会话id的操作。
/**
* 从mms数据库中检索threads表
*/
public void getMessageSessions(){
Cursor sessionCursor = null;
ContentResolver resolver = null;
ContactData contact = null;
try{
Uri uri = Uri.parse(SMS_URI_ALL);
resolver = mContext.getContentResolver();
sessionCursor = resolver.query(uri, new String[]
{ "* from threads--" }, null, null, null);
if (sessionCursor == null) {
return;
}
if (sessionCursor.getCount() == 0){
sessionCursor.close();
sessionCursor = null;
return;
}
sessionCursor.moveToFirst();
while (sessionCursor.isAfterLast() == false)
{
/*
threads表各字段含义如下:
1._id为会话id,他关联到sms表中的thread_id字段。
2.recipient_ids为联系人ID,这个ID不是联系人表中的_id,而是指向表canonical_address里的id,
canonical_address这个表同样位于mmssms.db,它映射了recipient_ids到一个电话号码,也就是说,
最终获取联系人信息,还是得通过电话号码;
3.mesage_count该会话的消息数量
4.snippet为最后收到或发出的信息
*/
int thread_idColumn = sessionCursor.getColumnIndex("_id");
int dateColumn = sessionCursor.getColumnIndex("date");
int message_countColumn = sessionCursor.getColumnIndex("message_count");
int snippetColumn = sessionCursor.getColumnIndex("snippet");
int typeColumn = sessionCursor.getColumnIndex("type");
//格式化短信日期显示
//SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = new Date(Long.parseLong(sessionCursor.getString(dateColumn)));
//获得短信的各项内容
//phoneAndUnread[0]存放电话号码,phoneAndUnread[1]存放该会话中未读信息数
String threadId = sessionCursor.getString(thread_idColumn);
String phoneAndUnread[]=getPhoneNum(threadId);
String last_mms=sessionCursor.getString(snippetColumn);
//String date_mms=dateFormat.format(date);
String date_mms=date.toString();
String count_mms=sessionCursor.getString(message_countColumn);
String type = sessionCursor.getString(typeColumn);
SMSInfo smsinfo = new SMSInfo();
/*
phoneAndUnread[0]存放电话号码
*/
contact = getContactFromPhoneNum(mContext, phoneAndUnread[0]);
//获得最后的未读短信与已读短信
//String final_count="("+phoneAndUnread[1]+"/"+count_mms+")";
//将会话信息添加到信息列表中
//判断是否联系人,若为联系人显示其名称,若不是则显示号码
if (contact.getContactName().equals("")){
smsinfo.setContactMes(phoneAndUnread[0]);
}else{
smsinfo.setContactMes(contact.getContactName());
}
//如果有该信息会话人头像,则设置已有头像,如果没有则给他设置一个默认的头像
if (contact.getPhotoUri() == null){
smsinfo.setContactPhoto(BitmapFactory.decodeResource(
mContext.getResources(), R.drawable.ic_launcher));
}else{
Uri photoUri = contact.getPhotoUri();
InputStream input = ContactsContract.Contacts.
openContactPhotoInputStream(resolver, photoUri);
smsinfo.setContactPhoto(BitmapFactory.decodeStream(input));
}
smsinfo.setDate(date_mms);
smsinfo.setSmsbody(last_mms);
smsinfo.setType(type);
smsinfo.setMessageCout(count_mms);
smsinfo.setThreadId(threadId);
infos.add(smsinfo);
sessionCursor.moveToNext();
}
sessionCursor.close();
}catch(Exception e){
Log.e(ThreadTAG,"E:" + e.toString());
}finally{
if (sessionCursor != null){
sessionCursor.close();
sessionCursor = null;
}
}
}
接着,需要为每个短信会话列表项监听点击事件,但某个会话被点击时就跳转到显示该会话下所有短信记录的界面,具体做法为在MessageListAdapter的getView()方法中添加红色代码如下:
<span style="font-size:14px;">public View getView(final 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.index_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));
4000
//将联系人信息载体Holder放入convertView视图
convertView.setTag(messageHolder);
}else{
//从convertView视图取出联系人信息载体Holder
messageHolder = (MessageHolder)convertView.getTag();
}
// 通过短信Holder设置item中4个TextView的文本与联系人头像
//绘制短信联系人信息,内容为其名称或号码
messageHolder.getTvTitle().setText(infos.get(position).getContactMes());
//在信息正文区域绘制信息内容
messageHolder.getTvDesc().setText(infos.get(position).getSmsbody());
messageHolder.getTvCount().setText(""+infos.get(position).getMessageCout());
messageHolder.getTvTime().setText(infos.get(position).getDate());
messageHolder.getIvImage().setImageBitmap(infos.get(position).getContactPhoto());
/*
* 在短信主界面为每个短信会话设置监听事件,当选择点击某条会话时,跳转到显示该会话包含的所有信息记录的页面
* */
convertView.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
Intent intent = new Intent();
//通过Intent向显示短信会话包含的信息的Activity传递会话id
intent.putExtra("threadId",infos.get(position).getThreadId());
intent.setClass(mContext, ShowSessionMessagesActivity.class);
mContext.startActivity(intent);
}
});
return convertView;
}</span>
通过上面的代码,可以看到当会话列表项被点击时,通过Intent跳转到负责显示会话信息记录页面的ShowSessionMessagesActivity,并传递该会话的threadId,,我们一起来看一下这Activity是怎样定义的吧。
<span style="font-size:14px;">package com.example.mymessageproject;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.widget.ListView;
import android.widget.TextView;
public class ShowSessionMessagesActivity extends Activity {
private ListView sessionMessagesListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_session_messages);
//使用Intent对象得到短信会话的id
Intent intent = getIntent();
String threadId = intent.getStringExtra("threadId");
sessionMessagesListView = (ListView)this.findViewById(R.id.SessionMessageListView);
ShowSessionMessagesAdapter sessionMessagesAdapter = new ShowSessionMessagesAdapter(this);
sessionMessagesAdapter.getSessionMessages(threadId);
sessionMessagesListView.setAdapter(sessionMessagesAdapter);
//实时通知数据已更新
sessionMessagesAdapter.notifyDataSetChanged();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.show_session_messages, menu);
return true;
}
}</span>
可以看到ShowSessionMessagesActivity的定义很简单,先通过Intent获取MessageListAdapter传过来的参数,即短信会话的threadId,然后获取用来显示会话记录的列表控件ListView,再将短信会话id传递给ListView的适配器类ShowSessionMessagesAdapter,最后为ListView设置适配器,就大功告成了,而在ShowSessionMessagesAdapter中又执行了什么操作呢,还是来看一下其代码吧。
package com.example.mymessageproject;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class ShowSessionMessagesAdapter extends BaseAdapter{
private LayoutInflater mInflater;
private Context mContext = null;
/**
* 所有的短信
*/
public static final String SMS_URI_ALL = "content://sms/";
private static final String GetMessagesByThreadIdTAG = "Getting messages by thread id";
//存储信息会话中所有来往短信的列表
List<SMSInfo> infos = new ArrayList<SMSInfo>();
//ShowSessionMessagesAdapter初始化构造方法
public ShowSessionMessagesAdapter(Context context) {
mContext = context;
mInflater = LayoutInflater.from(mContext);
}
/**
*
* @param 根据thread_id 检索sms库, 获得该会话包含的信息
* @return
*/
public void getSessionMessages(String thread_id){
Cursor sessionMessagesCursor = null;
ContentResolver resolver = null;
/**
获取短信的各种信息 ,短信数据库sms表结构如下:
_id:短信序号,如100
thread_id:对话的序号,如100,与同一个手机号互发的短信,其序号是相同的
address:发件人地址,即手机号,如+8613811810000
person:发件人,如果发件人在通讯录中则为具体姓名,陌生人为null
date:日期,long型,如1256539465022,可以对日期显示格式进行设置
protocol:协议0SMS_RPOTO短信,1MMS_PROTO彩信
read:是否阅读0未读,1已读
status:短信状态-1接收,0complete,64pending,128failed
type:短信类型1是接收到的,2是已发出
body:短信具体内容
service_center:短信服务中心号码编号,如+8613800755500
*/
try{
String[] projection = new String[]
{ "thread_id", "address", "person", "body", "date", "type","read" };
//Uri uri = Uri.parse("content://sms/");
Uri uri = Uri.parse(SMS_URI_ALL);
resolver = mContext.getContentResolver();
sessionMessagesCursor = resolver.query
(
uri,
projection,
"thread_id=?",
new String[] { thread_id } ,
null
);
if (sessionMessagesCursor == null) {
return;
}
if (sessionMessagesCursor.getCount() == 0){
sessionMessagesCursor.close();
sessionMessagesCursor = null;
return;
}
int nameColumn = sessionMessagesCursor.getColumnIndex("person");
int phoneNumberColumn = sessionMessagesCursor.getColumnIndex("address");
int smsbodyColumn = sessionMessagesCursor.getColumnIndex("body");
int dateColumn = sessionMessagesCursor.getColumnIndex("date");
int typeColumn = sessionMessagesCursor.getColumnIndex("type");
sessionMessagesCursor.moveToFirst();
while (sessionMessagesCursor.isAfterLast() == false){
SMSInfo smsinfo = new SMSInfo();
//将信息会话的信息内容和信息类型(收到或发出)存入infos中
smsinfo.setSmsbody(sessionMessagesCursor.getString(smsbodyColumn));
smsinfo.setType(sessionMessagesCursor.getString(typeColumn));
infos.add(smsinfo);
sessionMessagesCursor.moveToNext();
}
sessionMessagesCursor.close();
sessionMessagesCursor = null;
}catch(Exception e){
Log.e(GetMessagesByThreadIdTAG,"E:" + e.toString());
}finally{
if (sessionMessagesCursor != null){
sessionMessagesCursor.close();
sessionMessagesCursor = null;
}
}
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return infos.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return infos.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
MessageHolder receivedMessageHolder = null;
MessageHolder sendMessageHolder = null;
//判断convertView是否已创建,若已存在则不必重新创建新视图,节省系统资源
if (convertView == null) {
switch(Integer.parseInt(infos.get(position).getType())){
//若从sms表提取的信息type为1,说明这是收到的信息
case 1:
//为收到的信息关联格式文件,设置显示格式
convertView = mInflater.inflate(R.layout.message_session_list_received_item, null);
receivedMessageHolder = new MessageHolder();
receivedMessageHolder.setTvDesc((TextView) convertView.findViewById(
R.id.ReceivedSessionMessageTextView));
//将联系人信息载体Holder放入convertView视图
convertView.setTag(receivedMessageHolder);
break;
//若从sms表提取的信息type为其他,说明这是发出的信息
default:
//为发出的信息关联格式文件,设置显示格式
convertView = mInflater.inflate(R.layout.message_session_list_send_item, null);
sendMessageHolder = new MessageHolder();
sendMessageHolder.setTvDesc((TextView) convertView.findViewById(
R.id.SendSessionMessageTextView));
convertView.setTag(sendMessageHolder);
break;
}
}else{
//有convertView,按样式,从convertView视图取出联系人信息载体Holder
switch(Integer.parseInt(infos.get(position).getType()))
{
case 1:
receivedMessageHolder = (MessageHolder)convertView.getTag();
break;
default:
sendMessageHolder = (MessageHolder)convertView.getTag();
break;
}
}
//设置资源
switch(Integer.parseInt(infos.get(position).getType()))
{
case 1:
receivedMessageHolder.getTvDesc().setText(infos.get(position).getSmsbody());
break;
default:
sendMessageHolder.getTvDesc().setText(infos.get(position).getSmsbody());
break;
}
return convertView;
}
}
简要分析一下上面的代码。在getSessionMessages()方法中,通过会话id查询得到该会话包含的所有短信记录,并将其存入infos列表中,接下来,值得一提的是在getView()方法中根据短信的类型,即收到的或发出的对其进行区分显示,通过分别加载不同的格式定义xml文件来使其显示为不同的格式,用留空和背景颜色的不同来加以区分,最后,给出文章中的xml文件代码。
1.显示会话包含的信息记录的ShowSessionMessagesActivity的格式定义文件activity_show_session_messages.xml
2.定义收到短信格式的message_session_list_received_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/ReceivedSessionMessageTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_marginTop="10dip"
android:layout_marginBottom="10dip"
android:layout_marginRight="60dip"
android:textSize="20sp"
android:background="@color/gainsboro" />
<!-- gainsboro:淡灰色 -->
</RelativeLayout>
3.定义发出短信格式的message_session_list_send_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/SendSessionMessageTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dip"
android:layout_marginBottom="10dip"
android:layout_marginLeft="60dip"
android:textSize="20sp"
android:background="@color/powderblue" />
<!-- powderblue:粉蓝色 -->
</RelativeLayout>
4.颜色定义文件color.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="powderblue">#B0E0E6</color><!--粉蓝色 -->
<color name="gainsboro">#DCDCDC</color><!--淡灰色 -->
</resources>
参考文章链接:
http:// href="http://www.eoeandroid.com/forum.php?mod=viewthread&tid=200168" target=_blank>www.eoeandroid.com/forum.php?mod=viewthread&tid=200168
http://blog.163.com/ 9f7b
gis_warrior/blog/static/19361717320128149423856/
为了显示各个会话下所有的短信记录,需要取得短信会话的会话id,即sms表中的字段“thread_id”,而在上一篇文章中,我们已经在MessageListAdapter的getMessageSessions()方法中取得了每个短信会话的id,因此,我们还是先回去看一下吧,下面在getMessageSessions()中,红色代码部分执行了从threads表获取会话id的操作。
/**
* 从mms数据库中检索threads表
*/
public void getMessageSessions(){
Cursor sessionCursor = null;
ContentResolver resolver = null;
ContactData contact = null;
try{
Uri uri = Uri.parse(SMS_URI_ALL);
resolver = mContext.getContentResolver();
sessionCursor = resolver.query(uri, new String[]
{ "* from threads--" }, null, null, null);
if (sessionCursor == null) {
return;
}
if (sessionCursor.getCount() == 0){
sessionCursor.close();
sessionCursor = null;
return;
}
sessionCursor.moveToFirst();
while (sessionCursor.isAfterLast() == false)
{
/*
threads表各字段含义如下:
1._id为会话id,他关联到sms表中的thread_id字段。
2.recipient_ids为联系人ID,这个ID不是联系人表中的_id,而是指向表canonical_address里的id,
canonical_address这个表同样位于mmssms.db,它映射了recipient_ids到一个电话号码,也就是说,
最终获取联系人信息,还是得通过电话号码;
3.mesage_count该会话的消息数量
4.snippet为最后收到或发出的信息
*/
int thread_idColumn = sessionCursor.getColumnIndex("_id");
int dateColumn = sessionCursor.getColumnIndex("date");
int message_countColumn = sessionCursor.getColumnIndex("message_count");
int snippetColumn = sessionCursor.getColumnIndex("snippet");
int typeColumn = sessionCursor.getColumnIndex("type");
//格式化短信日期显示
//SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = new Date(Long.parseLong(sessionCursor.getString(dateColumn)));
//获得短信的各项内容
//phoneAndUnread[0]存放电话号码,phoneAndUnread[1]存放该会话中未读信息数
String threadId = sessionCursor.getString(thread_idColumn);
String phoneAndUnread[]=getPhoneNum(threadId);
String last_mms=sessionCursor.getString(snippetColumn);
//String date_mms=dateFormat.format(date);
String date_mms=date.toString();
String count_mms=sessionCursor.getString(message_countColumn);
String type = sessionCursor.getString(typeColumn);
SMSInfo smsinfo = new SMSInfo();
/*
phoneAndUnread[0]存放电话号码
*/
contact = getContactFromPhoneNum(mContext, phoneAndUnread[0]);
//获得最后的未读短信与已读短信
//String final_count="("+phoneAndUnread[1]+"/"+count_mms+")";
//将会话信息添加到信息列表中
//判断是否联系人,若为联系人显示其名称,若不是则显示号码
if (contact.getContactName().equals("")){
smsinfo.setContactMes(phoneAndUnread[0]);
}else{
smsinfo.setContactMes(contact.getContactName());
}
//如果有该信息会话人头像,则设置已有头像,如果没有则给他设置一个默认的头像
if (contact.getPhotoUri() == null){
smsinfo.setContactPhoto(BitmapFactory.decodeResource(
mContext.getResources(), R.drawable.ic_launcher));
}else{
Uri photoUri = contact.getPhotoUri();
InputStream input = ContactsContract.Contacts.
openContactPhotoInputStream(resolver, photoUri);
smsinfo.setContactPhoto(BitmapFactory.decodeStream(input));
}
smsinfo.setDate(date_mms);
smsinfo.setSmsbody(last_mms);
smsinfo.setType(type);
smsinfo.setMessageCout(count_mms);
smsinfo.setThreadId(threadId);
infos.add(smsinfo);
sessionCursor.moveToNext();
}
sessionCursor.close();
}catch(Exception e){
Log.e(ThreadTAG,"E:" + e.toString());
}finally{
if (sessionCursor != null){
sessionCursor.close();
sessionCursor = null;
}
}
}
接着,需要为每个短信会话列表项监听点击事件,但某个会话被点击时就跳转到显示该会话下所有短信记录的界面,具体做法为在MessageListAdapter的getView()方法中添加红色代码如下:
<span style="font-size:14px;">public View getView(final 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.index_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));
4000
//将联系人信息载体Holder放入convertView视图
convertView.setTag(messageHolder);
}else{
//从convertView视图取出联系人信息载体Holder
messageHolder = (MessageHolder)convertView.getTag();
}
// 通过短信Holder设置item中4个TextView的文本与联系人头像
//绘制短信联系人信息,内容为其名称或号码
messageHolder.getTvTitle().setText(infos.get(position).getContactMes());
//在信息正文区域绘制信息内容
messageHolder.getTvDesc().setText(infos.get(position).getSmsbody());
messageHolder.getTvCount().setText(""+infos.get(position).getMessageCout());
messageHolder.getTvTime().setText(infos.get(position).getDate());
messageHolder.getIvImage().setImageBitmap(infos.get(position).getContactPhoto());
/*
* 在短信主界面为每个短信会话设置监听事件,当选择点击某条会话时,跳转到显示该会话包含的所有信息记录的页面
* */
convertView.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
Intent intent = new Intent();
//通过Intent向显示短信会话包含的信息的Activity传递会话id
intent.putExtra("threadId",infos.get(position).getThreadId());
intent.setClass(mContext, ShowSessionMessagesActivity.class);
mContext.startActivity(intent);
}
});
return convertView;
}</span>
通过上面的代码,可以看到当会话列表项被点击时,通过Intent跳转到负责显示会话信息记录页面的ShowSessionMessagesActivity,并传递该会话的threadId,,我们一起来看一下这Activity是怎样定义的吧。
<span style="font-size:14px;">package com.example.mymessageproject;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.widget.ListView;
import android.widget.TextView;
public class ShowSessionMessagesActivity extends Activity {
private ListView sessionMessagesListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_session_messages);
//使用Intent对象得到短信会话的id
Intent intent = getIntent();
String threadId = intent.getStringExtra("threadId");
sessionMessagesListView = (ListView)this.findViewById(R.id.SessionMessageListView);
ShowSessionMessagesAdapter sessionMessagesAdapter = new ShowSessionMessagesAdapter(this);
sessionMessagesAdapter.getSessionMessages(threadId);
sessionMessagesListView.setAdapter(sessionMessagesAdapter);
//实时通知数据已更新
sessionMessagesAdapter.notifyDataSetChanged();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.show_session_messages, menu);
return true;
}
}</span>
可以看到ShowSessionMessagesActivity的定义很简单,先通过Intent获取MessageListAdapter传过来的参数,即短信会话的threadId,然后获取用来显示会话记录的列表控件ListView,再将短信会话id传递给ListView的适配器类ShowSessionMessagesAdapter,最后为ListView设置适配器,就大功告成了,而在ShowSessionMessagesAdapter中又执行了什么操作呢,还是来看一下其代码吧。
package com.example.mymessageproject;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class ShowSessionMessagesAdapter extends BaseAdapter{
private LayoutInflater mInflater;
private Context mContext = null;
/**
* 所有的短信
*/
public static final String SMS_URI_ALL = "content://sms/";
private static final String GetMessagesByThreadIdTAG = "Getting messages by thread id";
//存储信息会话中所有来往短信的列表
List<SMSInfo> infos = new ArrayList<SMSInfo>();
//ShowSessionMessagesAdapter初始化构造方法
public ShowSessionMessagesAdapter(Context context) {
mContext = context;
mInflater = LayoutInflater.from(mContext);
}
/**
*
* @param 根据thread_id 检索sms库, 获得该会话包含的信息
* @return
*/
public void getSessionMessages(String thread_id){
Cursor sessionMessagesCursor = null;
ContentResolver resolver = null;
/**
获取短信的各种信息 ,短信数据库sms表结构如下:
_id:短信序号,如100
thread_id:对话的序号,如100,与同一个手机号互发的短信,其序号是相同的
address:发件人地址,即手机号,如+8613811810000
person:发件人,如果发件人在通讯录中则为具体姓名,陌生人为null
date:日期,long型,如1256539465022,可以对日期显示格式进行设置
protocol:协议0SMS_RPOTO短信,1MMS_PROTO彩信
read:是否阅读0未读,1已读
status:短信状态-1接收,0complete,64pending,128failed
type:短信类型1是接收到的,2是已发出
body:短信具体内容
service_center:短信服务中心号码编号,如+8613800755500
*/
try{
String[] projection = new String[]
{ "thread_id", "address", "person", "body", "date", "type","read" };
//Uri uri = Uri.parse("content://sms/");
Uri uri = Uri.parse(SMS_URI_ALL);
resolver = mContext.getContentResolver();
sessionMessagesCursor = resolver.query
(
uri,
projection,
"thread_id=?",
new String[] { thread_id } ,
null
);
if (sessionMessagesCursor == null) {
return;
}
if (sessionMessagesCursor.getCount() == 0){
sessionMessagesCursor.close();
sessionMessagesCursor = null;
return;
}
int nameColumn = sessionMessagesCursor.getColumnIndex("person");
int phoneNumberColumn = sessionMessagesCursor.getColumnIndex("address");
int smsbodyColumn = sessionMessagesCursor.getColumnIndex("body");
int dateColumn = sessionMessagesCursor.getColumnIndex("date");
int typeColumn = sessionMessagesCursor.getColumnIndex("type");
sessionMessagesCursor.moveToFirst();
while (sessionMessagesCursor.isAfterLast() == false){
SMSInfo smsinfo = new SMSInfo();
//将信息会话的信息内容和信息类型(收到或发出)存入infos中
smsinfo.setSmsbody(sessionMessagesCursor.getString(smsbodyColumn));
smsinfo.setType(sessionMessagesCursor.getString(typeColumn));
infos.add(smsinfo);
sessionMessagesCursor.moveToNext();
}
sessionMessagesCursor.close();
sessionMessagesCursor = null;
}catch(Exception e){
Log.e(GetMessagesByThreadIdTAG,"E:" + e.toString());
}finally{
if (sessionMessagesCursor != null){
sessionMessagesCursor.close();
sessionMessagesCursor = null;
}
}
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return infos.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return infos.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
MessageHolder receivedMessageHolder = null;
MessageHolder sendMessageHolder = null;
//判断convertView是否已创建,若已存在则不必重新创建新视图,节省系统资源
if (convertView == null) {
switch(Integer.parseInt(infos.get(position).getType())){
//若从sms表提取的信息type为1,说明这是收到的信息
case 1:
//为收到的信息关联格式文件,设置显示格式
convertView = mInflater.inflate(R.layout.message_session_list_received_item, null);
receivedMessageHolder = new MessageHolder();
receivedMessageHolder.setTvDesc((TextView) convertView.findViewById(
R.id.ReceivedSessionMessageTextView));
//将联系人信息载体Holder放入convertView视图
convertView.setTag(receivedMessageHolder);
break;
//若从sms表提取的信息type为其他,说明这是发出的信息
default:
//为发出的信息关联格式文件,设置显示格式
convertView = mInflater.inflate(R.layout.message_session_list_send_item, null);
sendMessageHolder = new MessageHolder();
sendMessageHolder.setTvDesc((TextView) convertView.findViewById(
R.id.SendSessionMessageTextView));
convertView.setTag(sendMessageHolder);
break;
}
}else{
//有convertView,按样式,从convertView视图取出联系人信息载体Holder
switch(Integer.parseInt(infos.get(position).getType()))
{
case 1:
receivedMessageHolder = (MessageHolder)convertView.getTag();
break;
default:
sendMessageHolder = (MessageHolder)convertView.getTag();
break;
}
}
//设置资源
switch(Integer.parseInt(infos.get(position).getType()))
{
case 1:
receivedMessageHolder.getTvDesc().setText(infos.get(position).getSmsbody());
break;
default:
sendMessageHolder.getTvDesc().setText(infos.get(position).getSmsbody());
break;
}
return convertView;
}
}
简要分析一下上面的代码。在getSessionMessages()方法中,通过会话id查询得到该会话包含的所有短信记录,并将其存入infos列表中,接下来,值得一提的是在getView()方法中根据短信的类型,即收到的或发出的对其进行区分显示,通过分别加载不同的格式定义xml文件来使其显示为不同的格式,用留空和背景颜色的不同来加以区分,最后,给出文章中的xml文件代码。
1.显示会话包含的信息记录的ShowSessionMessagesActivity的格式定义文件activity_show_session_messages.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".ShowSessionMessagesActivity" > <ListView android:id="@+id/SessionMessageListView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignTop="@+id/intentDataTextView" > </ListView> </RelativeLayout>
2.定义收到短信格式的message_session_list_received_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/ReceivedSessionMessageTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_marginTop="10dip"
android:layout_marginBottom="10dip"
android:layout_marginRight="60dip"
android:textSize="20sp"
android:background="@color/gainsboro" />
<!-- gainsboro:淡灰色 -->
</RelativeLayout>
3.定义发出短信格式的message_session_list_send_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/SendSessionMessageTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dip"
android:layout_marginBottom="10dip"
android:layout_marginLeft="60dip"
android:textSize="20sp"
android:background="@color/powderblue" />
<!-- powderblue:粉蓝色 -->
</RelativeLayout>
4.颜色定义文件color.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="powderblue">#B0E0E6</color><!--粉蓝色 -->
<color name="gainsboro">#DCDCDC</color><!--淡灰色 -->
</resources>
参考文章链接:
http:// href="http://www.eoeandroid.com/forum.php?mod=viewthread&tid=200168" target=_blank>www.eoeandroid.com/forum.php?mod=viewthread&tid=200168
http://blog.163.com/ 9f7b
gis_warrior/blog/static/19361717320128149423856/
相关文章推荐
- 基于Android的短信应用开发(七)——导航栏ActionBar显示与短信会话删除
- 基于Android的短信应用开发(三)——读取手机短信
- 基于Eclipse的Android JNI层測试应用开发过程记录
- 基于Android的短信应用开发(六)——将发出短信存至数据库
- 基于Android的短信应用开发(一)——界面设计开发
- android: 用ContentResolver读取自己应用的短信和手机通话记录(15)
- 三、东软实践项目2-基于android平台的应用开发:打电话功与发短信功能
- 基于Android的短信应用开发(八)——通过上下文菜单ContextMenu选中删除单条短信
- 基于Eclipse的Android JNI层测试应用开发过程记录
- Android短信开发相关信息记录
- 基于C#开发Windows Mobile应用中短信发送功能(转)
- 原创:Android应用开发记录-Andorid歌词秀(4)完成,含源码
- 1.1搭建基于Eclipse的Android应用开发环境
- 原创:Android应用开发记录-Andorid歌词秀(3)使用的Service的音频播放器
- 原创:Android应用开发记录-Andorid歌词秀(2)先来一个音频播放器
- Android手机在开发调试时logcat不显示输出信息的解决办法
- 招聘信息显示苹果开发iOS地图应用
- android开发-使用Toast显示提示信息框
- android 用MyEclipse开发时LogCat不显示控制台信息解决办法
- Android开发中遇到读取数据库中的短信问题