3

Let's brute force your garden-variety Android 2.x Visible Contact ID/Names cursor (via ContactsContract):

Cursor c = getContentResolver().query(
  Contacts.CONTENT_URI,
  new String[] { Contacts._ID, Contacts.DISPLAY_NAME },
  Contacts.IN_VISIBLE_GROUP + " = '1'",
  null,
  Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"
);

Is there a way to filter this to get contacts that only have at least one email and/or phone number?

I see that I can use Contacts.HAS_PHONE_NUMBER ... but I don't see HAS_EMAIL anywhere. (Tell me this isn't going to get ugly.)

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Joe D'Andrea
  • 5,141
  • 6
  • 49
  • 67

2 Answers2

4

Query on the appropriate content provider Uri. For example, android.provider.ContactsContract.CommonDataKinds.Email lets you obtain email addresses, and your other columns (e.g., IN_VISIBLE_GROUP) are implicitly joined in.

Here is a sample project that demonstrates using these other content provider Uri values.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Mark comes through! Many thanks. I will take Spinners for a, um, spin. I should clarify, however. I realize I can always walk the contacts individually, but I'm trying to get the filtered list in one fell swoop. – Joe D'Andrea Jan 06 '11 at 03:35
  • @Joe D'Andrea: "but I'm trying to get the filtered list in one fell swoop" ...which is what the sample I supplied demonstrates. You need to take advantage of the implicit joins that the `ContactsContract` content provider supplies when you query "secondary" "tables" like `CommonDataKinds.Email`. – CommonsWare Jan 06 '11 at 12:40
  • Perfect. That's what I'm missing - the implicit joins. (Now to try and get Eclipse to import the project!) – Joe D'Andrea Jan 06 '11 at 14:05
  • @Joe D'Andrea: Yeah, this is one of the reasons why I don't like content providers -- you have no way of doing joins yourself, and you're relying upon limited documentation to figure out what joins might be done on your behalf. – CommonsWare Jan 06 '11 at 14:18
  • @CommonsWare: Sigh, yes, it's very frustrating. I think I need to botch the managedQuery just to see what the SQL is and reverse engineer from there. I'm essentially trying to write a buildEmailPhonesAdapter, that is, I want to pull contacts with an email and/or phone number, not separately. I'm sure I'm missing the implicit joins. For instance, I don't think it's enough to just add Phone.NUMBER to an Email Adapter PROJECTION - apart from probably being wrong anyway (what about folks w/phone #s but no emails?). – Joe D'Andrea Jan 06 '11 at 14:57
  • @Joe D'Andrea: "I want to pull contacts with an email and/or phone number, not separately" -- oof, not sure if that's possible. – CommonsWare Jan 06 '11 at 15:12
0

I just enumerated the columns on a cursor fetched on Contacts like that:

Cursor c = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
String[] names = c.getColumnNames();
for (String string : names) {
    Log.d("ContactList", "RC column " + string);
}
c.close();

The result contains has_email. It may be specific to the galaxy tab, though.

njzk2
  • 38,969
  • 7
  • 69
  • 107