2011-06-15 54 views
3

我試圖查詢ContactContract的ContentProvider並獲得以下算法將獲取的數據:安卓:ContactsContract查詢,需要更先進的選擇字符串

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 '?'" 

導致運行時錯誤 「結合或列索引超出範圍...」。所以這必須是一些語法錯誤...對嗎? ContentProvider查詢的正確語法是什麼和/或我如何從ContactsContract得到結果集?

回答

8

對ContentProvider的查詢有點不同,並且對格式化不予考慮。對於ContentProviders,如果要將'%'用作通配符,則必須將'%'連接到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位數字,則需要完全匹配。

+0

我有這個(種)查詢一個問題,直到我注意到Data.CONTENT_URI的使用,而不是CONTENT_FILTER_URI。我剛剛意識到我的語義誤解。謝謝你的提示。 – Shoham 2014-08-21 12:20:46

0

使用ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER而不是ContactsContract.CommonDataKinds.Phone.NUMBER