0

How do I query all contacts matching a certain criteria on Android?

Let´s say, I want to have all contacts, which have a name, a phone number, but no profile picture.

As I understand the SQL thing, I need some kind of selection, which is passed to my query, but how would it exactly look in the example above?

I´m asking, because I´m currently running an app which first queries all contacts and after that I iterate through it and filter it, which seems much less performant then querying directly the right contacts

Marian Klühspies
  • 15,824
  • 16
  • 93
  • 136

1 Answers1

3

You are correct in the sense that contacts are stored in a SQLite database, but they are accessed via the Contacts Content Provider.

The Contacts Content Provider is organized in a three table fashion. At the bottom of the data structure lies the Data table. Here you will find all data that pertains to a specific RawContact (will discuss shortly). The Data table stores information like phone numbers, emails, addresses,etc. It does so by using MIME name value pairs defined on the mimetypes database. Up one level is the RawContacts database. Here all the information that pertains to the same account (i.e. Contact John Doe may have a twitter and Facebook account). In short, the RawContacts table keeps track of Data MIME types that pertain to the same person so there is no need to store the same information multiple times for different accounts. At the top of the data structure you have the Contacts table that groups all the information for a single person. It is basically a way of unifying all account information into one contact. Think of this contacts as you regularly would.

You should take a look at the Loader class which will allow you to perform queries on a background Thread. If you use this class once you implement the Loader callback for the Cursor, you will create a CursorLoader. One of its constructors parameter is A typical MySQL where clause where you can specify the constraints you want to include as part of your query.

Here you would find a guide to Loaders to query a database.

Emmanuel
  • 13,083
  • 4
  • 39
  • 53
  • Hey, thank you for your useful answer :) The thing with the three was kind of clear before. Thank you for the Loader advice, didnßt know that and wrote all asynchronous logic by my self^^ The constraints I can pass to the loader should be exactly the same I can simply pass to getContentResolver().query(...),right? My problem is, I have really no knowledge about sql and it´s statements and I need to specify filters, so that the cursor points to a dataset of filtered entries. There should be no difference between a Cursor from a Loader and a self defined one – Marian Klühspies Jul 11 '13 at 16:51
  • It is actually the same as doing getContentResolver.query(). You can look online for SQLite tutorials. For example, on the where parameter of the CursorLoader you can say "_id = 1. I believe the _I'd column is required in every SQLite table that is why I picked it. You pass that as String into the constructor and it should return the first row of data. Then you can add more constrains using 3VL operators (or,and, etc). If you have a name column you can pass "_id = 1 and name=John Doe". That will return the first row if the name column has John Doe as its value. – Emmanuel Jul 11 '13 at 17:06
  • Okay.But would something like this be valid? Can I even say xyz != 1? String selection = ContactsContract.Contacts.DISPLAY_NAME + " = '" + 1 + "' AND " + ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '" + 1 + "' AND NOT"+ContactsContract.Contacts.PHOTO_ID; – Marian Klühspies Jul 11 '13 at 17:10
  • Did this answer your question? If so can you mark this post as answered. – Emmanuel Jul 11 '13 at 22:55