java - Android: ContactsContract查询,需要更高级的选择字符串

标签 java android contacts android-contentprovider

我正在尝试查询 ContactContract ContentProvider 并获取以下算法将获取的数据:

given a phone number (input), return record...:
if(recordNumber has 7 digits) {
    if('%recordNumber' LIKE 'inputNumber') {
        return recordDisplayName;
    }
} else if(recordNumber has 10 digits) {
    if('recordNumber' LIKE '%inputNumber') {
        return recordDisplayName;
    }
} else if(recordNumber == inputNumber) {
    return recordDisplayName;
}

这在查询调用中有效:

ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE ?"

但我需要更多这样的东西:

"('%" + ContactsContract.CommonDataKinds.Phone.NUMBER+"' LIKE '?' AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=7) OR ('" + ContactsContract.CommonDataKinds.Phone.NUMBER+"' LIKE '%?' AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=10)"

但每次我使用带单引号的查询时都会出现运行时错误。例如,改变:

ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE ?"

到:

ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE '?'"

导致运行时错误“绑定(bind)或列索引超出范围...”。所以这一定是一些语法错误......对吧? ContentProvider 查询的正确语法是什么和/或我如何从 ContactsContract 获取结果集?

最佳答案

对 ContentProvider 的查询有点不同,并且在格式上没有宽容度。对于 ContentProvider,如果您想使用“%”作为通配符,则“%”必须连接到 WHERE 子句中的参数,而不是作为子句本身的一部分。

正确:

Cursor cursor = getContentResolver().query(
    ContactsContract.Data.CONTENT_URI, 
    null, 
    ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE ?",
    new String[] { "%"+number },
    null);

不正确:

Cursor cursor = getContentResolver().query(
    ContactsContract.Data.CONTENT_URI, 
    null, 
    ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE %?", 
    new String[] { number }, 
    null);

上面的“不正确”语句对于 SQLite 查询实际上是完全合法的,只是对于 ContentProvider 查询不合法。

此外,单引号是 ContentProvider 查询的 WHERE 子句(或连接到所述子句中的参数)中的语法错误。

最终代码:

if(number.length()==7) {
    cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, 
        ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE ?",
        //"('%" + ContactsContract.CommonDataKinds.Phone.NUMBER+"' LIKE '?' AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=7) OR ('" + ContactsContract.CommonDataKinds.Phone.NUMBER+"' LIKE '%?' AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=10)",
        new String[] { "%"+number },
        null);
} else if(number.length()==10) {
    cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, 
        "("+ContactsContract.CommonDataKinds.Phone.NUMBER+"=? AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=7) OR ("+ContactsContract.CommonDataKinds.Phone.NUMBER+"=? AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=10)",
        new String[] { number.substring(3), number },
        null);
} else {
    cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, 
        ContactsContract.CommonDataKinds.Phone.NUMBER+"=?",
        new String[] { number },
        null);
}

此代码将检索与相关号码匹配的电话号码的匹配显示名称。
- 如果号码是 7 位号码,我们检索电话号码最后 7 位数字(破折号和特殊字符,除了“*”和“#”,因为它们是有效的电话字符)匹配号码中的 7 位数字的任何记录问题。
- 如果数字是 10 位数字,它返回任何包含 7 位数字并匹配最后 7 个字符的记录,或者在记录有 10 位数字的情况下包含完全匹配的记录。
- 如果有问题的数字既不是 7 位也不是 10 位数字,则需要完全匹配。

关于java - Android: ContactsContract查询,需要更高级的选择字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6361681/

相关文章:

java - 如何使用 XML Java DOM 重新排序节点

android - 如何使用 sax 解析器解析像这样丑陋的结构化 XML

android - 具有多个没有标题的 PreferenceScreen 的 PreferenceActivity

ios - 联系电话 iphone sdk

java - Apache Common MultiValueMap 迭代

Java:使用比较器和属性的第二个字对对象列表进行排序

java - 安卓:基频

java - 在 xml 解析中查看 android 的 flipper 示例

javascript - 下拉动画联系人框

java - 尝试访问 Android 中的联系人时权限被拒绝