`

在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[i];
                    String column = mProjectionMap.get(userColumn);

                    if (column != null) {
                        projection[i] = column;
                        continue;
                    }

                    if (!mStrictProjectionMap &&
                            ( userColumn.contains(" AS ") || userColumn.contains(" as "))) {
                        /* A column alias already exist */
                        projection[i] = userColumn;
                        continue;
                    }

                    throw new IllegalArgumentException("Invalid column "
                            + projectionIn[i]);
                }

    变量mStrictProjectionMap的值是由第一段代码设置为了true,因而在构建查询语句时,想将待查的表名做个别名的机会也没有了。

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics