2

I am currently using the ContentProvider for contacts to retrieve the contacts from the device and allowing the user to filter the results by typing into an EditText.

To do so I have set up a filter query on a SimpleAdapter as follows:

    contactsAdapter.setFilterQueryProvider(new FilterQueryProvider() {
        String[] PROJECTION = new String[] {
                ContactsContract.Contacts._ID,
                ContactsContract.Contacts.DISPLAY_NAME,
                ContactsContract.Contacts.HAS_PHONE_NUMBER,
        };
        String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED COLLATE NOCASE ASC";

          public Cursor runQuery(CharSequence constraint) {
            String SELECTION = "LOWER(" + ContactsContract.Contacts.DISPLAY_NAME + ")" 
            + " LIKE '" + constraint + "%' " + "and " + ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'";
            Cursor cur = managedQuery(ContactsContract.Contacts.CONTENT_URI, 
                    PROJECTION, SELECTION, null, sortOrder);
            return cur; 
          }
        });
    setListAdapter(contactsAdapter); 

This works in most cases however when I have a contact with an accent (Example: Tést Cóntact) then I want the contact to show up even if the user types in Test Contact, currently it doesn't.

Also the case is not ignored in this case either whereas for standard characters it is, for example if I have a contact called Omar and search for omar it matches but if I have a contact called Ómar and search for ómar it doesn't match.

Does anyone know what I should be doing to implement the behavior I want to achieve?

Donal Rafferty
  • 19,239
  • 37
  • 110
  • 186

3 Answers3

0

You can use the replace function to remove the accented characters. Look at this simple solution:

How to SQL compare columns when one has accented chars?

Community
  • 1
  • 1
Derzu
  • 6,253
  • 1
  • 49
  • 56
0

See my question Using COLLATE in Android SQLite - Locales is ignored in LIKE statement

Short answer - I think it's impossible to use the LIKE statement in Android SQLite and ignore accents. I solved it by making a new column in the database, where you store the same name without accents and in lower case. For example Column 1 stores "Tést Cóntact" - which is used for display and Column 2 stores "test contact" - which is used for using the LIKE statement. Android 2.3 has a Normalizer class which will remove all accents from a string. If you are supporting lower Android API, then you may need to write your own normalizer somehow...

Community
  • 1
  • 1
Daniel Novak
  • 2,590
  • 3
  • 25
  • 36
  • how exactly do you suggest to add a column to the android Contacts contentprovider? – njzk2 Dec 06 '11 at 13:06
  • I'm using the Contacts ContentProvider though, not my own database, so I'm guessing thats not an option unless I scrap my current code and implement my own database? – Donal Rafferty Dec 06 '11 at 13:06
  • Oops, sorry I didn't notice the ContentProvider part in your question. I don't know an optimal solution to this. There is a bug report at http://code.google.com/p/quickdroid/issues/detail?id=1#c2 and the user in comment #2 mentions that the LIKE statement works correctly with accents from Android 2.3, which could be also why they added the Normalizer class in Android 2.3... – Daniel Novak Dec 06 '11 at 13:32
0

I would see 2 options here :

  • Create a table that contains accent-less version of the contacts names and a reference to the actual contact Id
  • Replace accented caracters by ? in your search (which may result in not really user expected behaviour, but is so much simpler)
njzk2
  • 37,030
  • 6
  • 63
  • 102
  • Neither will work in my case as I am pulling the data from the Contacts Content Provider. – Donal Rafferty Dec 06 '11 at 13:47
  • actually, both would work. I wistook '?' with '_' which is a single wildcard. You simply replace all you accentuated charaters in your search field by '_', but it will match more than you'd like. You can also create a table that mirrors the actual Contacts table. This implies some complexity in order to be in good sync, but it can be done with contentObservers – njzk2 Dec 06 '11 at 15:50