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

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


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

短信、彩信的数据库的结构和模型讲解见:http://www.cnblogs.com/shaweng/archive/2012/05/26/2518949.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出去后,编译不过会报错。你只要把换行删掉就可以了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章