您的位置:首页 > 移动开发 > Android开发

android 导出每个号码的最新的短信记录(巧用SQL语句的"--"注释符)

2014-03-17 21:57 381 查看
最近在做一个项目,要求:导出每个号码最新的短信记录,要求显示人名,号码,最近的一条短信内容且以时间降序排列。

短信数据库存储路径:“./data/data/com.android.providers.telephony/databases/mmssms.db”

短信、彩信的数据库的结构和模型讲解见:/article/5125700.html

目前的方法有五种:

方法一:

SQL语句为:select date, body, address, type from sms where (length(address)>0) group by (thread_id) order by date desc

但是不能够导出草稿记录

void getSmsData(Context cnt) {
ContentResolver resolver = cnt.getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(Sms.CONTENT_URI, new String[] {
Telephony.Sms.DATE,
Telephony.Sms.BODY, Telephony.Sms.ADDRESS,
Telephony.Sms.TYPE },
"length(" + Telephony.Sms.ADDRESS + ")>0) group by ("
+ Telephony.Sms.THREAD_ID, null, Telephony.Sms.DEFAULT_SORT_ORDER);
// 提高cursor访问速度
if (cursor != null) {
int count = cursor.getCount();
cursor.moveToFirst();
synchronized (mImportDataList) {//正序查找
for (int i = 0; i < count; i++) {
cursor.moveToPosition(i);
long smsDate = cursor.getLong(0);//设置最新一条短信的时间
String smsBody = cursor.getString(1); // 內容
String phoneNum = cursor.getString(2); // 电话号码
int smsType = cursor.getInt(3); // 短信类型
Log.i("DEBUG", "smsDate = " + smsDate + ",smsBody="
+ smsBody +
",phoneNum=" + phoneNum + ",smsType=" + smsType);
}
}
cursor.close();
}
} catch (Exception e) {
Log.w(TAG, e.toString());
cursor = null;
} finally {
if (cursor != null) {
cursor.close();
}
}
}


方法二:

SQL 语句:

select a.date,a.snippet,b.address,b.type from threads a, sms b where a._id = b.thread_id group by b.address order by a.date desc --from sms

多表查询,同时查询表threads和sms。即先查出thread_ID,然后取出该thread_ID对应的电话号码和内容等

参考网址:http://bbs.csdn.net/topics/340237133

但是也不能够导出草稿记录

void getSmsData(Context cnt) {
ContentResolver resolver = cnt.getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(Sms.CONTENT_URI,new String[] {
" a.date,a.snippet",
" b.address,b.type from threads a",
" sms b where a._id = b.thread_id  group by b.address order by a.date desc-- ",
}, null, null, null);
// 提高cursor访问速度
if (cursor != null) {
int count = cursor.getCount();
cursor.moveToFirst();
synchronized (mImportDataList) {//正序查找
for (int i = 0; i < count; i++) {
cursor.moveToPosition(i);
long smsDate = cursor.getLong(0);//设置最新一条短信的时间
String smsBody = cursor.getString(1); // 內容
String phoneNum = cursor.getString(2); // 电话号码
int smsType = cursor.getInt(3); // 短信类型
Log.i("DEBUG", "smsDate = " + smsDate + ",
smsBody=" +
smsBody + ",phoneNum=" + phoneNum   + ",smsType=" + smsType);
}
}
cursor.close();
}
} catch (Exception e) {
Log.w(TAG, e.toString());
cursor = null;
} finally {
if (cursor != null) {
cursor.close();
}
}
}


方法三:

SQL 语句:

select a.date,a.snippet,b.address,b.type from threads a, sms b where a._id = b.thread_id group by a.date --from sms

它是方法二的变种,能够转换为android方式的查询数据库。

注意该方式的弊端是,无法满足不同号码的短信的时间相同时,会漏掉短信。因为它是以日期为group by。实现方式如下:

void getSmsData(Context cnt) {
ContentResolver resolver = cnt.getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(Sms.CONTENT_URI,new String[] {
" a.date,a.snippet",
" b.address,b.type from threads a",
" sms b where a._id = b.thread_id  group by b.date-- ",
}, null, null, null);
// 提高cursor访问速度
if (cursor != null) {
int count = cursor.getCount();
cursor.moveToFirst();
synchronized (mImportDataList) {//正序查找
for (int i = 0; i < count; i++) {
cursor.moveToPosition(i);
long smsDate = cursor.getLong(0);//设置最新一条短信的时间
String smsBody = cursor.getString(1); // 內容
String phoneNum = cursor.getString(2); // 电话号码
int smsType = cursor.getInt(3); // 短信类型
Log.i("DEBUG", "smsDate = " + smsDate + ",smsBody=" +
smsBody + ",phoneNum=" + phoneNum   + ",smsType=" + smsType);
}
}
cursor.close();
}
} catch (Exception e) {
Log.w(TAG, e.toString());
cursor = null;
} finally {
if (cursor != null) {
cursor.close();
}
}
}


方法四:

SQL 语句:

select a.date,a.snippet,c.type,b.address from threads a,canonical_addresses b , sms c where a.recipient_ids = b._id and c.date = a.date and c.thread_id = a._id and c.body >= a.snippet group by b.address order by a.date desc -- from sms

改变查询策略,查询表threads ,canonical_addresses ,sms

但是无法导出彩信记录

注意:sql语句中的"--"代表注释,所以

select a.date,a.snippet,c.type,b.address from threads a,canonical_addresses b , sms c where a.recipient_ids = b._id and c.date = a.date and c.thread_id = a._id and c.body >= a.snippet group by b.address order by a.date
desc -- from sms

等同于

select a.date,a.snippet,c.type,b.address from threads a,canonical_addresses b , sms c where a.recipient_ids = b._id and c.date = a.date and c.thread_id = a._id and c.body >=
a.snippet group by b.address order by a.date desc

所以上面的sql语句是一个很巧妙的方式满足了在ContentResolver 中查询也能够允许自定义的sql语句

void getSmsData(Context cnt) {
ContentResolver resolver = cnt.getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(Sms.CONTENT_URI,new String[] {
" a.date,a.snippet,a.type",
" b.address from threads a",
" canonical_addresses b",
" sms c where a.recipient_ids = b._id and
c.date = a.date and c.thread_id =
a._id and c.body >= a.snippet
group by b.address order by a.date desc -- ",
}, null, null, null);
// 提高cursor访问速度
if (cursor != null) {
int count = cursor.getCount();
cursor.moveToFirst();
synchronized (mImportDataList) {
for (int i = 0; i < count; i++) {
cursor.moveToPosition(i);
long smsDate = cursor.getLong(0);//设置最新一条短信的时间
String smsBody = cursor.getString(1); // 內容
String phoneNum = cursor.getString(3); // 电话号码
int smsType = cursor.getInt(2); // 短信类型
Log.i("DEBUG", "smsDate = " + smsDate + ",smsBody=" +
smsBody + ",phoneNum=" + phoneNum   + ",smsType=" + smsType);
}
}
cursor.close();
}
} catch (Exception e) {
Log.w(TAG, e.toString());
cursor = null;
} finally {
if (cursor != null) {
cursor.close();
}
}
}


方法五:

终极大招,牛逼的SQL语句:

select address,date,body,type from (select a.address as address,c.date as date

,b.snippet as body,c.type as type from canonical_addresses a,threads b

, sms c where a._id = b.recipient_ids and b._id = c.thread_id and c.body >= b.snippet and c.date = b.date union

select c.address as address,b.date as date,a.sub as body,a.msg_box

as type from pdu a,threads b,canonical_addresses

c where a.thread_id = b._id and b.recipient_ids = c._id ) group by address order by date desc

它即能够导出sms、mms、草稿等。

void getSmsData(Context cnt) {
ContentResolver resolver = cnt.getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(Sms.CONTENT_URI,new String[] {
"date,body,type,
address from (select a.address
as address,c.date as date",
"b.snippet as body,c.type
as type from canonical_addresses
a,threads b , sms c where
a._id = b.recipient_ids
and b._id = c.thread_id
and c.body >= b.snippet
and c.date = b.date union
select c.address as
address,b.date as date
,a.sub as body,a.msg_box
as type from pdu a,threads
b,canonical_addresses
c where a.thread_id
= b._id and
b.recipient_ids = c._id
) group by address order by date desc --",
}, null, null, null);
// 提高cursor访问速度
if (cursor != null) {
int count = cursor.getCount();
cursor.moveToFirst();
synchronized (mImportDataList) {
for (int i = 0; i < count; i++) {
cursor.moveToPosition(i);
long smsDate = cursor.getLong(0);//设置最新一条短信的时间
String smsBody = cursor.getString(1); // 內容
String phoneNum = cursor.getString(3); // 电话号码
int smsType = cursor.getInt(2); // 短信类型
Log.i("DEBUG", "smsDate = " + smsDate + ",smsBody=" +
smsBody + ",phoneNum=" + phoneNum   + ",smsType=" + smsType);
}
}
cursor.close();
}
} catch (Exception e) {
Log.w(TAG, e.toString());
cursor = null;
} finally {
if (cursor != null) {
cursor.close();
}
}
}


综上所述:

使用方法五即简单也能够满足需求和解决边界值问题。所以使用方法四来导入最新短信记录。

注意:由于为了让内容能够在网页里面显示,有一些代码是直接换行了,copy出去后,编译不过会报错。你只要把换行删掉就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: