2017-06-28 13 views
0

Imは、デバイスの連絡先に次のクエリを実行しようとしているCASE行うことはできません:。getContentResolverを使用してクエリ()クエリ()

final String[] PROJECTION = { 
     ContactsContract.CommonDataKinds.Phone._ID, 
     ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY, 
     ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY, 
     ContactsContract.CommonDataKinds.Phone.NUMBER, 
     String.format("CASE WHEN " + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " LIKE '%%%s%%' THEN 'full' END name_match", mFirstName) 
}; 

String SELECTION = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " LIKE ?"; 

String[] selectionArgs = {mFirstName}; 

String ORDER_BY = "name_match ASC"; 

Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, SELECTION, selectionArgs, ORDER_BY); 

をしかし、私は次の例外を取得:

           java.lang.IllegalArgumentException: Invalid column CASE WHEN display_name LIKE '%john%' THEN 'full' END name_match 
               at android.database.sqlite.SQLiteQueryBuilder.computeProjection(SQLiteQueryBuilder.java:632) 
               at android.database.sqlite.SQLiteQueryBuilder.buildQuery(SQLiteQueryBuilder.java:447) 
               at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:387) 
               at com.android.providers.contacts.ContactsProvider2.query(ContactsProvider2.java:7812) 
               at com.android.providers.contacts.ContactsProvider2.queryLocal(ContactsProvider2.java:7550) 
               at com.android.providers.contacts.ContactsProvider2.query(ContactsProvider2.java:6037) 
               at android.content.ContentProvider$Transport.query(ContentProvider.java:238) 
               at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112) 
               at android.os.Binder.execTransact(Binder.java:453) 

ここで何が間違っていますか?コンテンツプロバイダーでCASE WHENクエリを実行することは可能ですか?連絡先のテーブルに?そうでない場合は、そのようなクエリを実行する代替手段はありますか?

ありがとうございました。

+0

あなたが何をすべきかをしようとしていますか?代わりに 'LIKE%?%'をチェックしてみてください。それは投影に入れて意味がありません... – marmor

+0

私は問題に集中するコードを短縮しました。私はいくつかの他の事例条件を取り除いた。何をしようとしているのは、名前の一致結果 - 完全一致/名一致/姓一致を含む別の列を持つことです。 – AsafK

+0

私はAOSPコードを少し見ましたが、mStrictというSQLiteQueryBuilderのクラス変数があります。 trueに設定すると、実際のテーブルの列の他にSELECT部分​​の何かを使用することはできません。もちろん、連絡先のプロバイダはそれをtrueに設定しています。私はそれを取得しないでください... – AsafK

答えて

0

の代わりにあなたが(不可能だ)のContentProviderに欲しいものをやって、あなたはかなり簡単にコードでそれを行うことができます。

final String[] projection = { ... }; 
String selection = Phone.DISPLAY_NAME_PRIMARY + " LIKE %?%"; 
String[] selectionArgs = { mFirstName }; 
Cursor cursor = cr.query(Phone.CONTENT_URI, projection, selection, selectionArgs, null); 
List<String> fullMatch = new ArrayList<>(); 
List<String> partialMatch = new ArrayList<>(); 
while (cursor.moveToNext()) { 
    String name = cursor.getString(3); // exact number depends on your projection 
    if (mFirstName.equalsIgnoreCase(name) { 
     fullMatch.add(name); 
    } else { 
     partialMatch.add(name); 
    } 
} 
cursor.close(); 
List<String> allMatches = new ArrayList<>(); 
allMatches.addAll(fullMatch); 
allMatches.addAll(partialMatch); 
+0

はるかに効率的です。とにかくありがとう。 – AsafK

関連する問題