Reputation: 874
I'm trying to retrieve the address of a contact using the activity's content resolver. There is no Address field anywhere. I tried ContactsContract.CommonDataKinds.StructuredPostal.STREET but it also gives me a different value. Please see the screen shot of how the field looks like in android which I'm trying to retrieve.
In my code below, I'm iterating through all values in the CONTENT_URI for 'John Doe', but this address, "Slaughter Lane" never shows up i.e. my breakpoint at the Timber log command 'Found the address' is never hit.
fun getContact(activity: FragmentActivity, name: String): Contact? {
var contact = Contact()
val cr : ContentResolver = activity.contentResolver
var selectionArgs: Array<String> = arrayOf("John Doe")
val cursor = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
"DISPLAY_NAME = ?",
selectionArgs,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"
)
if (cursor != null) {
try {
while (cursor.moveToNext()) {
cursor.columnNames.forEach {
var stringValue: String? = cursor.getString(cursor.getColumnIndex(it))
if (stringValue!=null) {
if (stringValue.contains("Slaughter")){
Timber.i("Found the address");
}
}
}
}
} finally {
cursor.close()
}
}
return if (contact.name != null) contact else null
}
Upvotes: 2
Views: 574
Reputation: 153
fun getAddress(rawContactId: Long): String? {
val contentResolver = context.contentResolver
val projection: Array<out String> = arrayOf(
ContactsContract.Data.CONTACT_ID,
ContactsContract.Data.MIMETYPE,
ContactsContract.Data.DATA1,
ContactsContract.Data.DATA2,
)
val selection = "${ContactsContract.Data.CONTACT_ID} = ?"
val selectionArgs: Array<String> = arrayOf("")
selectionArgs[0] = rawContactId.toString()
val cursor = contentResolver.query(
ContactsContract.Data.CONTENT_URI,
projection,
selection,
selectionArgs,
null
)
var address: String? = null
cursor?.apply {
while (moveToNext()) {
if (rawContactId == getLong(getColumnIndex(ContactsContract.Data.CONTACT_ID))) {
val mimeType: String = getString(getColumnIndex(ContactsContract.Data.MIMETYPE))
if (mimeType == ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE)
address = getString(getColumnIndex(ContactsContract.Data.DATA1))
}
}
}
cursor?.close()
return address
}
Upvotes: 1
Reputation: 28199
The code you posted doesn't show how you're trying to access StructuredPostal.STREET
, but I think I understand how you tried to do it.
When you query over Phone.CONTENT_URI
you will only receive general contact info (such as Data.CONTACT_ID and Data.DISPLAY_NAME) plus phone specific columns (such as Phone.NUMBER), because each row will be of mimetype Phone.CONTENT_ITEM_TYPE
.
You can't get address info from that query.
If you need multiple types of information (like phone AND address), you need to query over the more generic Data.CONTENT_URI
uri, and then use the Data.MIMETYPE
to figure out what type of row is this, phone, address, or something else... you can limit the types of rows you receive by adding a selection over Data.MIMETYPE
.
Here's example code (in java):
String[] projection = {Data.CONTACT_ID, Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1, Data.DATA2, Data.DATA3};
// query only phones and addresses
String selection = Data.MIMETYPE + " IN ('" + Phone.CONTENT_ITEM_TYPE + "', '" + StructuredPostal.CONTENT_ITEM_TYPE + "')";
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);
while (cur != null && cur.moveToNext()) {
long id = cur.getLong(0);
String name = cur.getString(1); // full name
String mime = cur.getString(2); // type of data (phone / address)
String data = cur.getString(3); // the actual info, e.g. +1-212-555-1234
String kind = "unknown";
switch (mime) {
case Phone.CONTENT_ITEM_TYPE:
kind = "phone";
break;
case StructuredPostal.CONTENT_ITEM_TYPE:
kind = "address";
break;
}
Log.d(TAG, "got " + id + ", " + name + ", " + kind + " - " + data);
}
cur.close();
you may get multiple phones and addresses for the same contact, so if you need it per contact you should add a HashMap from id
to the data you need.
Upvotes: 0