Accent insensitive query in the contacts provider - android

I want to make a contacts query where the selection is in the form Phone.DISPLAY_NAME_PRIMARY + " LIKE ?, but I want the search to be accent insensitive.
If I use COLLATE LOCALIZED, it works with the = operator, not with the like.
Android's default contact app somehow manages to do that.

Instead of making a query to ContactsContract.Data.CONTENT_URI and using a "selection", make a query to ContactsContract.Contacts.CONTENT_FILTER_URI where the query is added as an additional path segment.

Related

Using ContactsContract, query matching name or email

Is it possible to do one query to ContactsContract to get a set of contacts which match either the display name or a phone number or an email address?
This is essentially a join of the Contacts and Data "tables" (in quotes because they only look like tables through the interface but may not be).
In other words, I'd like a where clause something like (simplifying the syntax a bit)
where Contacts.DISPLAY_NAME like "%?%"
or (Data.MIMETYPE = Phone.CONTENT_ITEMTYPE
and CommonDataKinds.Phone.NUMBER like "%?%")
or (Data.MIMETYPE = Email.CONTENT_ITEMTYPE
and CommonDAtaKinds.Email.ADDRESS like "%?%")
and the tables are joined like
Data.RAW_CONTACT_ID = RawContacts.ID and RawContacts.CONTACT_ID = Contacts.ID
I could do this as separate queries without the join, but then ordering the results becomes difficult. I'd like them ordered by display name.
If you only want to match name/email/phone then you can do:
WHERE Data.MIMETYPE IN (StructuredName.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE, Email.CONTENT_ITEM_TYPE)
AND Data.DATA1 LIKE "%?%"
If you're ok with extending the possible match fields, then you can simplify the query to:
WHERE Data.DATA1 LIKE "%?%"
This will match CommonDataKinds.StructuredName.DISPLAY_NAME, CommonDataKinds.Email.ADDRESS, CommonDataKinds.Phone.NUMBER, and more.
The answer was stairing me in the face.
The Data table is already a join (or looks like one, maybe it is a denormalized table internally). Thus, all I need to do is query for all three matches directly:
where Data.DISPLAY_NAME like "%?%"
or (Data.MIMETYPE = Phone.CONTENT_ITEMTYPE
and CommonDataKinds.Phone.NUMBER like "%?%")
or (Data.MIMETYPE = Email.CONTENT_ITEMTYPE
and CommonDAtaKinds.Email.ADDRESS like "%?%")
Note the Data.DISPLAY_NAME, above.

android sql how to handle large Query 200000 lines database?

i use this code to give suggestions to the user when typing. but one query takes lot of time. is there a way to speed up?
String cnql = "SELECT DISTINCT sinhala FROM jgd WHERE sinhala LIKE '"+gg+"%' LIMIT 0,4";
Cursor cg=cn.rawQuery(cnql, null);
You can create a virtual table for full text searching on Android which provides a very quick way to retrieve matching strings. However, it does require you set up and maintain a separate FTS virtual table and populate it with the strings you want to search. As its focus is full text search, it does not support a 'starts with' type of operator, although you can gg + "*" to search for words prefixed with your search query.

Search data from sqlite3 database in android

I have a Sqlite3 database in android, with data are sentences like: "good afternoon" or "have a nice day", now I want to have a search box, to search between them, I use something like this :
Cursor cursor = sqliteDB.rawQuery("SELECT id FROM category WHERE sentences LIKE '"+ s.toString().toLowerCase()+ "%' LIMIT 10", null);
But it only show "good afternoon" as result if user start searching with first "g" or "go" or "goo" or etc, how can I retrieve "good afternoon" as results, if user search like "a" or "af" or "afternoon".
I mean I want to show "good afternoon" result, if user search from middle of a data in sqlite3 db, not only if user searches from beginning.
thanks!
Just put the percent sign in front of your query string: LIKE '%afternoon%'. However, your approach has two flaws:
It is susceptible to SQL injection attacks because you just insert unfiltered user input into your SQL query string. Use the query parameter syntax instead by re-writing your query as follows:
SELECT id FROM category WHERE sentences LIKE ? LIMIT 10. Add the user input string as selection argument to your query method call
It will be dead slow the bigger your database grows because LIKE queries are not optimized for quick string matching and lookups.
In order to solve number 2 you should use SQLite's FTS3 extension which greatly speeds up any text-related searches. Instead of LIKE you would be using the MATCH operator that uses a different query syntax:
SELECT id FROM category WHERE sentences MATCH 'afternoon' LIMIT 10
As you can see the MATCH operator does not need percent signs. It just tries to find any occurrence of a word in the whole text that is being searched (in your case the sentences column). Read through the documentation of FTS3 I've linked to. The MATCH query syntax provides some more pretty handy and powerful options for finding text in your database table which are pretty similar to early search engine query syntax such as:
MATCH 'afternoon OR evening'
The only (minor) downside to the FTS3 extension is that it blows up the database file size by creating additional search index tables and meta-data. But I think it's well worth it for this use case.

Distinct and substri in android with sqlite

I want get the first letter for all contacts without repetition i can't use something like this:
Cursor flc = this.cr.query(ContactsContract.Contacts.CONTENT_URI,
Proyection2, null, null, "UPPER("+ContactsContract.Contacts.DISPLAY_NAME+")");
Because Content providers don't allow functions in proyection with code this is explanation that i want:
"Select distinct substr(" + ContactsContract.Contacts.DISPLAY_NAME+",
1, 1) from "+ContactsContract.Contacts.CONTENT_URI "
I search a method for do this with content providers or accesing directly to bd but i don't know how.
Content providers are not a generic SQL interface; they support only those accesses that they have implemented, and they might not be based on an SQL database in the first place.
If you want to do any filtering or grouping not directly supported by a content provider, you have to do it yourself.

Is it possible have something like the GROUP BY clause in an Android managedQuery?

I'm planning to support Android devices from 2.0 onwards so I am using a managedQuery to query contacts. I get multiple results for people with the same name and phone number so I would like those results to be grouped. (That is I want each name and phone number combination to be unique)
IS it possicle to group these results in a managed query (similar to the GROUP BY clause in SQL)
Mel
You can use a hack in the selection statement like "1) GROUP BY (" + Phone.DISPLAY_NAME;.

Categories

Resources