android学习笔记31--------------短信会话列表信息的获取

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


这几天一直纠结于系统短信的界面,再查了n多资料后,终于自己写了个短信会话信息的界面,并仿照系统自带短信界面,得到了联络人与陌生人号码,还有最后接收的短信及其他信息。

关于短信的各种操作在我的另一篇博客里讲:

http://blog.csdn.net/yf210yf/article/details/7268904

这里略做补充点:

盗了别人两个图:

sms表,信息表


threads表


Threads的URI为:"content://mms-sms/conversations"

不过由于本人使用这个Uri查询出错,故使用content://sms/ 通过构造查询字段数组来查询Threads表。

	ContentResolver cr = getContentResolver();
		Cursor cursor = cr.query(Uri.parse("content://mms/"), new String[]
		{ "* from threads--" }, null, null, null);

另一些补充的知识:

Android 中涉及数据库查询的地方一般都会有一个 query() 方法,而这些 query 中有大都(全部?)会有一个参数 selectionArgs,比如下面这个 android.database.sqlite.SQLiteDatabase.query():


public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) 
public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)

    selection 参数很好理解,就是 SQL 语句中 WHERE 后面的部分,即过滤条件, 比如可以为 id=3 AND name='Kevin Yuan' 表示只返回满足 id 为 3 且 name 为 "Kevin Yuan" 的记录。

    再实际项目中像上面那样简单的“静态”的 selection 并不多见,更多的情况下要在运行时动态生成这个字符串,比如

public doQuery(long id, final String name) 
{  
  mDb.query("some_table", // table name   
        null, // columns  
        "id=" + id + " AND name='" + name + "'", // selection  
         //...... 更多参数省略  
  );  
} 

public doQuery(long id, final String name)

{
  mDb.query("some_table", // table name
        null, // columns
        "id=" + id + " AND name='" + name + "'", // selection
         //...... 更多参数省略
  );
}


在这种情况下就要考虑一个字符转义的问题,比如如果在上面代码中传进来的 name 参数的内容里面有单引号('),就会引发一个 "SQLiteException syntax error .... "。

     手工处理转义的话,也不麻烦,就是 String.replace() 调用而已。但是 Android SDK 为我们准备了 selectionArgs 来专门处理这种问题:

public void doQuery(long id, final String name) 
{  
  mDb.query("some_table", // table name   
        null, // columns  
        "id=" + id + " AND name=?", // selection  
        new String[] {name}, //selectionArgs  
         //...... 更多参数省略  
  );  
  // ...... 更多代码  
} 

public void doQuery(long id, final String name)

{
  mDb.query("some_table", // table name
        null, // columns
        "id=" + id + " AND name=?", // selection
        new String[] {name}, //selectionArgs
         //...... 更多参数省略
  );
  // ...... 更多代码
}

也就是说我们在 selection 中需要嵌入字符串的地方用 ? 代替,然后在 selectionArgs 中依次提供各个用于替换的值就可以了。在 query() 执行时会对 selectionArgs 中的字符串正确转义并替换到对应的 ? 处以构成完整的 selection 字符串。 有点像 String.format()。

    不过需要注意的是 ? 并不是“万金油”,只能用在原本应该是字符串出现的地方。比如下面的用法是错误的:

public void doQuery(long id, final String name) 
{  
  mDb.query("some_table", // table name   
        null, // columns  
        "? = " + id + " AND name=?", // selection XXXX 错误!? 不能用来替换字段名  
        new String[]{"id", name}, //selectionArgs  
      //...... 更多参数省略  
  );  
  // ...... 更多代码  
}


部分程序:

/**
	 * 从mms数据库中检索threads表 
	 */
	public void getContacts_LastMessage()
	{
		ContentResolver cr = getContentResolver();
		Cursor cursor = cr.query(Uri.parse("content://mms/"), new String[]
		{ "* from threads--" }, null, null, null);
		
		while (cursor.moveToNext())
		{
			int thread_id = cursor.getColumnIndex("_id");
			int date = cursor.getColumnIndex("date");
			int message_count = cursor.getColumnIndex("message_count");
			int snippet = cursor.getColumnIndex("snippet");
						
 			//格式化短信日期显示
			SimpleDateFormat sfd = new SimpleDateFormat("MM-dd hh:mm:ss");
			Date date_format = new Date(Long.parseLong(cursor.getString(date)));
			String time = sfd.format(date_format);
			
			//获得短信的各项内容
			String info[]=getPhoneNum(cursor.getString(thread_id));
			String last_mms=cursor.getString(snippet);
			String date_mms=time;
			String count_mms=cursor.getString(message_count);
			
			//判断是否联系人
            String contact = getContactNameFromPhoneNum(this
					.getApplicationContext(), info[0]);
            
            //获得最后的未读短信与已读短信
            String final_count="("+info[1]+"/"+count_mms+")";
            
            //添加到list
            if (contact.equals(""))
			{
				getData(
						info[0], 
						last_mms,
						final_count,
						date_mms
					   );
			}
			else 
			{
				getData(
						contact, 
						last_mms,
						final_count,
						date_mms
						);
			}
		}

	}

/**
	 * 
	 * @param 根据thread_id 检索sms库, 获得对应的号码
	 * @return
	 */
	public String[] getPhoneNum(String thread_id)
	{
		String PhoneNum="";
		int noread_mms=0;
		String[] info={"",""};
		String[] projection = new String[]
		{ "thread_id", "address", "person", "body", "date", "type","read" };
		
		Uri uri = Uri.parse("content://sms/");
		ContentResolver cr = getContentResolver();			
		
		Cursor cursor = cr.query
		(
				uri, 
				projection, 
				"thread_id=?",
				new String[] { thread_id } ,
				null
		);
		
		while (cursor.moveToNext())
		{
			int phoneNumber = cursor.getColumnIndex("address");
			int isread =cursor.getColumnIndex("read");
			
			if (cursor.getString(isread).equals("0"))
			{
				noread_mms++;
			}
			
			PhoneNum=cursor.getString(phoneNumber);	
		}
		info[0]=PhoneNum;
		info[1]=Integer.toString(noread_mms);
		
		return info;				
	}

Cursor cursor = cr.query
(
uri, 
projection, 
"thread_id=?",
new String[] { thread_id } ,
"date asc"   //按日期正序排   "date desc" //按日期倒序排
);


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值