http://www.cppcode.com/archives/2012/03/31/252.html
读取Android短信
Android系统短信数据库解析请看这里:
Android短信数据库简析
读取短信会话列表:
“短信会话列表”其实就是说你的手机中存在着多少个人的短信,一个联系人与你来往的所有短信称作一个会话,如下图的短信会话列表中,一共有三个会话。
其中第一个会话,是与KAT的短信来往,一共有三条短信。
第二个会话,是与Sam的短信来往,一共有六条短信。
以Same的会话为例,点进去之后,会出现与Sam的所有短信记录,叫作一个会话(thread),如下右图:
那么如何来获取系统的短信会话列表(左图),如何来获取某一个会话中的所有短信记录呢(右图)?
我们一共需要操作三个表,如果还需要显示联系人姓名的话,就需要操作更多的表(系统联系人数据库中的表),短信数据库中是没有存储联系人姓名的……
获取系统短信会话列表:
如下图:上面上系统短信数据库中所有的短信,下面是Eclipse中得出的结果,打出的Log…
先从threads表中获取一个列表,通过threads表中的recipient_ids字段到canonical_addresses中查询号码。通过threads表中的_id字段到sms表中查询短信的其它项(短信内容,短信类型,短信状态,发送日期等等)
注:threads表中的recipient_ids字段就是canonical_addresses表中的_id字段
Threads表中的_id字段就是sms表中的thread_id字段。
千万不要想当然地以为threads表中的_id字段与recipient_ids字段是相同的,其实,虽然大部分时间他们的值是一样的,但有时候,它们也会不一样……
好了,说了这么多,也该上代码了,现在我们就要通过JAVA代码来真正地操作Android系统的短信数据库了。但是,我们会遇到一个问题:Android没有提供公开可用的,操作系统短信的包,也就是说我们找不到Android系统短信数据库的URI。呵呵,解决办法很简单,在Android SDK目录中,路径如下:
\android-sdk-windows\android-sdk-windows\sources\android-15\android\provider\Telephony.java,在这个类里有定义系统短信,只不过,被隐藏了,想用的话,也简单:只需要到Android SDK的目录里将Telephony.java文件复制出来,放到你的项目中当作你自己的类来使用就行了,一般情况下,大家都会将其放在:android.provider.Telephonyp 这个包里。这样的话,我们可以直接这样导包:
import android.provider.Telephony.Sms;
import android.provider.Telephony.Threads;
接下来就可以操作短信数据库了:数据库操作类如下:
package com.contact.main.database;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.Telephony.Sms;
import android.provider.Telephony.Threads;
import android.util.Log;import java.text.SimpleDateFormat;
import java.util.Date;public class SystemSmsManager {
private static final String TAG = SystemSmsManager.class.getSimpleName();private static SystemSmsManager sInstance;
private Context mContext;
private SystemSmsManager(final Context c) {
mContext = c;
}public static void init(Context c) {
if (sInstance == null) {
sInstance = new SystemSmsManager(c);
}
}public static SystemSmsManager getInstance() {
if (null == sInstance) {
throw new RuntimeException("please first call init(c)");
}
return sInstance;
}public void test() {
Log.d(TAG, "Just a Test, Print All System Sms…");
final ContentResolver contentResolver = mContext.getContentResolver();
Cursor cursor = contentResolver.query(Sms.CONTENT_URI, null, null, null, null);
if (null != cursor) {
while (cursor.moveToNext()) {
int _id = cursor.getInt(cursor.getColumnIndex(Sms._ID));
int thread_id = cursor.getInt(cursor.getColumnIndex(Sms.THREAD_ID));
String address = cursor.getString(cursor.getColumnIndex(Sms.ADDRESS));
String body = cursor.getString(cursor.getColumnIndex(Sms.BODY));
Log.d(TAG, "_id:" + _id + "___" + "thread_id:" + thread_id + "___" + "address:"
+ address + "___" + "body:" + body);}
}
}public void getSysSmsThreadId() {
final ContentResolver contentResolver = mContext.getContentResolver();
Uri sAllThreadsUri = Threads.CONTENT_URI.buildUpon().appendQueryParameter("simple", "true")
.build();
Cursor cursor = contentResolver.query(sAllThreadsUri, null, null, null, null);
if (null != cursor) {
while (cursor.moveToNext()) {
long id = cursor.getLong((cursor
.getColumnIndex(android.provider.Telephony.ThreadsColumns._ID)));
int msgcount = cursor.getInt((cursor
.getColumnIndex(android.provider.Telephony.ThreadsColumns.MESSAGE_COUNT)));
long ids = cursor.getLong((cursor
.getColumnIndex(android.provider.Telephony.ThreadsColumns.RECIPIENT_IDS)));
Log.v(TAG, "会话ID:" + id + "有" + msgcount + "条短信");
getNumberByIds(ids);
getThreadSms(id);}
cursor.close();
}
}public void getThreadSms(long threadId) {
final ContentResolver contentResolver = mContext.getContentResolver();
Cursor cursor = contentResolver.query(Sms.CONTENT_URI, null, Sms.THREAD_ID + " = ‘"
+ threadId + "’", null, Sms.DATE + " asc");
if (null != cursor) {
while (cursor.moveToNext()) {
String number = cursor.getString(cursor.getColumnIndex(Sms.ADDRESS));
String body = cursor.getString(cursor.getColumnIndex(Sms.BODY));
int type = cursor.getInt(cursor.getColumnIndex(Sms.TYPE));
long date = cursor.getLong(cursor.getColumnIndex(Sms.DATE));
String[] mdate = convertDate(date);
String typeCN = type == 1 ? "发件箱" : "收件箱";
Log.d(TAG, typeCN + ":Number:[" + number + "] 短信内容:" + body + " 时间:["
+ mdate[0] + " " + mdate[1] + "]");
}
cursor.close();
}
}private static Uri sSingleCanonicalAddressUri = Uri
.parse("content://mms-sms/canonical-addresses");private String getNumberByIds(long ids) {
String address = "";
final ContentResolver contentResolver = mContext.getContentResolver();
Cursor cursor = contentResolver.query(sSingleCanonicalAddressUri, null, "_id = ‘" + ids
+ "’", null, null);
if (null != cursor) {
if (cursor.moveToFirst()) {
address = cursor.getString(1);
Log.w(TAG, "会话列表显示号码为:" + address);
}
cursor.close();
}
return address;
}/**
* @param date
* @return 数组含有两个元素,第一个是date,第二个是time
*/
public static final String[] convertDate(long dateInSys) {
Date dt = new Date(dateInSys);
SimpleDateFormat formatDate = new SimpleDateFormat("MM-dd");
SimpleDateFormat formatTime = new SimpleDateFormat("HH:mm");
String date = formatDate.format(dt);
String time = formatTime.format(dt);
String myDate[] = new String[] {
date, time
};
return myDate;
}public static final String FormatDateForBackup(long date) {
Date dt = new Date(date);
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return format1.format(dt);
}
Trackback