xwv 发表于 2013-1-14 18:01:24

在Android中自由查询系统联系人数据库的一次实践

  实践来源于下面的想法:
   在调用
   getContentResolver().query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
   时,是否可以在系统构造的查询语句中,为等待查询的表使用一个别名。
 
   通过Google查找后,发现下面两个web:
   1.android 自由操作系统数据库
   2.android 中管理短信      
   其中提供的方法是:在方法query的参数projection中,使用注释符,将系统拼凑的内容注释掉;而自己的语句全都放在了参数
projection中。下面是一段来自1)的例子:
   select * from sms as a join threads as b where a._id = 1 order by a.date desc– from sms where () order by date desc
  相应的query方法为
  getContentResolver().query( Uri.parse("content://sms/") , new String[]{"* from sms as a join threads as b where a._id = 1 order by a.date desc--"}, null, null, null)
   按照这个思路,首先测试了提供的例子,成功后在系统联系人数据库查询中使用此方法实现之前的想法,但是产生错误。日志信息类似下面:
    Caused by: java.lang.IllegalArgumentException: Invalid column ......


    原因在哪里?
    下面这个web中,作者为‘DMH‘的回答,可以解释这个错误的原因。
    IllegalArgumentException: Invalid column
    回头查看logcat日志输出,依次查看了Android的源码:
    com.android.providers.contacts.ContactsProvider2
    android.database.sqlite.SQLiteQueryBuilder
    之后明白了其中的原因。
    在com.android.providers.contacts.ContactsProvider2中构建查询时,使用下面的代码:
   

qb.setStrictProjectionMap(true);    而在android.database.sqlite.SQLiteQueryBuilder的方法computeProjection中,有如下代码:
   

for (int i = 0; i < length; i++) {                  String userColumn = projectionIn;                  String column = mProjectionMap.get(userColumn);                  if (column != null) {                        projection = column;                        continue;                  }                  if (!mStrictProjectionMap &&                            ( userColumn.contains(" AS ") || userColumn.contains(" as "))) {                        /* A column alias already exist */                        projection = userColumn;                        continue;                  }                  throw new IllegalArgumentException("Invalid column "                            + projectionIn);                }    变量mStrictProjectionMap的值是由第一段代码设置为了true,因而在构建查询语句时,想将待查的表名做个别名的机会也没有了。
页: [1]
查看完整版本: 在Android中自由查询系统联系人数据库的一次实践