How to get the first name and last name from Android contacts?
How to get the following fields from Android contacts? I used Android 2.2.
- Name prefix
- First name
- Middle name
- Last name
- Name prefix
- Ph开发者_开发技巧onetic given name
- Phonetic middle name
- Phonetic family name
Look at ContactsContract.CommonDataKinds.StructuredName
class. You can find there all columns you are looking for. Try sth like this:
String whereName = ContactsContract.Data.MIMETYPE + " = ?";
String[] whereNameParams = new String[] { ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE };
Cursor nameCur = contentResolver.query(ContactsContract.Data.CONTENT_URI, null, whereName, whereNameParams, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
while (nameCur.moveToNext()) {
String given = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
String family = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
String display = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
}
nameCur.close();
It returns all names in contacts. To be more precise you can add a contact id as an additional parameter to the query - you will get address for particular contact.
For a specified contact you can do this :
String whereName = ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " = ?";
String[] whereNameParams = new String[] { ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE, contact_ID };
Cursor nameCur = contentResolver.query(ContactsContract.Data.CONTENT_URI, null, whereName, whereNameParams, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
while (nameCur.moveToNext()) {
String given = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
String family = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
String display = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
}
nameCur.close();
As the other example (just for fun) but for fetching contact name of a single user:
// A contact ID is fetched from ContactList
Uri resultUri = data.getData();
Cursor cont = getContentResolver().query(resultUri, null, null, null, null);
if (!cont.moveToNext()) {
Toast.makeText(this, "Cursor contains no data", Toast.LENGTH_LONG).show();
return;
}
int columnIndexForId = cont.getColumnIndex(ContactsContract.Contacts._ID);
String contactId = cont.getString(columnIndexForId);
// Fetch contact name with a specific ID
String whereName = ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " = " + contactId;
String[] whereNameParams = new String[] { ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE };
Cursor nameCur = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, whereName, whereNameParams, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
while (nameCur.moveToNext()) {
String given = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
String family = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
String display = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
Toast.makeText(this, "Name: " + given + " Family: " + family + " Displayname: " + display, Toast.LENGTH_LONG).show();
}
nameCur.close();
cont.close();
try to use this code to get the required information about the contact,the code is here-
import android.provider.ContactsContract.Contacts;
import android.database.Cursor;
// Form an array specifying which columns to return, you can add more.
String[] projection = new String[] {
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone
ContactsContract.CommonDataKinds.Email
};
Uri contacts = ContactsContract.Contacts.CONTENT_LOOKUP_URI;
// id of the Contact to return.
long id = 3;
// Make the query.
Cursor managedCursor = managedQuery(contacts,
projection, // Which columns to return
null, // Which rows to return (all rows)
// Selection arguments (with a given ID)
ContactsContract.Contacts._ID = "id",
// Put the results in ascending order by name
ContactsContract.Contacts.DISPLAY_NAME + " ASC");
Some links to get you started, in addition to the suggestions from Raunak:
- http://www.higherpass.com/Android/Tutorials/Working-With-Android-Contacts/
- How to obtain all details of a contact in Android
- http://developer.android.com/resources/samples/ContactManager/index.html
Experimenting with the ContactsContract.Data.CONTENT_URI
in late 2015 on marshmallow. I'm unable to get the GIVEN_NAME
or similar fields. I think the later apis have deprecated these. Run the following code to print out the columns you have on your phone
Uri uri = ContactsContract.Data.CONTENT_URI;
String selection = ContactsContract.Data.MIMETYPE + " = ?";
String[] selectionArgs = new String[] { ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE};
Cursor cursor = contentResolver.query(
uri, // URI representing the table/resource to be queried
null, // projection - the list of columns to return. Null means "all"
selection, // selection - Which rows to return (condition rows must match)
selectionArgs, // selection args - can be provided separately and subbed into selection.
null); // string specifying sort order
if (cursor.getCount() == 0) {
return;
}
Log.i("Count:", Integer.toString(cursor.getCount())); // returns number of names on phone
while (cursor.moveToNext()) {
// Behold, the firehose!
Log.d(TAG, "-------------------new record\n");
for(String column : cursor.getColumnNames()) {
Log.d(TAG, column + ": " + cursor.getString(cursor.getColumnIndex(column)) + "\n");
}
}
try this,
public void onActivityResult(int reqCode, int resultCode, Intent data) { super.onActivityResult(reqCode, resultCode, data);
try {
if (resultCode == Activity.RESULT_OK) {
Uri contactData = data.getData();
Cursor cur = managedQuery(contactData, null, null, null, null);
ContentResolver contect_resolver = getContentResolver();
if (cur.moveToFirst()) {
String id = cur.getString(cur.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
String name = "";
String no = "";
Cursor phoneCur = contect_resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
if (phoneCur.moveToFirst()) {
name = phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
no = phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
Log.e("Phone no & name :***: ", name + " : " + no);
txt.append(name + " : " + no + "\n");
id = null;
name = null;
no = null;
phoneCur = null;
}
contect_resolver = null;
cur = null;
// populateContacts();
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
Log.e("IllegalArgumentException::", e.toString());
} catch (Exception e) {
e.printStackTrace();
Log.e("Error :: ", e.toString());
}
}
Combining various solutions here, and seeing there are duplicate records from the results (due to multiple accounts), I've decided to make a function that will prioritize common account-types over others. On this sample, I also ignore the records of completely empty/null names (if all are as such), but you can change this if you wish:
@RequiresPermission(
allOf = [Manifest.permission.READ_CONTACTS])
@WorkerThread
fun getContactIdToContactNameMap(context: Context): LongSparseArray<ContactObject> {
val contactIdToContactObjectMap = LongSparseArray<ContactObject>()
val contentResolver = context.contentResolver
contentResolver.query(ContactsContract.Data.CONTENT_URI,
arrayOf(
ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID,
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME,
ContactsContract.RawContacts.ACCOUNT_TYPE),
ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.Data.IN_VISIBLE_GROUP + " = ?",
arrayOf(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE, "1"),
null)?.use { cursor ->
// Log.d("AppLog", "got ${cursor.count} records for names")
val colContactId = cursor.getColumnIndex(
ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID)
val colFirstName = cursor.getColumnIndex(
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME)
val colFamilyName = cursor.getColumnIndex(
ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME)
val colMiddleName = cursor.getColumnIndex(
ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME)
val colAccountType =
cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE)
val googleAccount = "com.google"
//https://stackoverflow.com/a/44802016/878126
val prioritizedAccountTypes =
hashSetOf("vnd.sec.contact.phone", "com.htc.android.pcsc",
"com.sonyericsson.localcontacts", "com.lge.sync", "com.lge.phone",
"vnd.tmobileus.contact.phone", "com.android.huawei.phone",
"Local Phone Account",
"")
val contactIdToAccountTypeMap = LongSparseArray<String>()
while (cursor.moveToNext()) {
val contactId = cursor.getLong(colContactId)
val accountType = cursor.getString(colAccountType).orEmpty()
val existingContact = contactIdToContactObjectMap.get(contactId)
if (existingContact != null) {
//this can occur, as we go over all of the items, including duplicate ones made by various sources
// https://stackoverflow.com/a/4599474/878126
val previousAccountType = contactIdToAccountTypeMap.get(contactId)
//google account is most prioritized, so we skip current one if previous was of it
if (previousAccountType == googleAccount)
continue
if (accountType != googleAccount && previousAccountType != null && prioritizedAccountTypes.contains(
previousAccountType))
//we got now a name of an account that isn't prioritized, but we already had a prioritized one, so ignore
continue
}
contactIdToAccountTypeMap.put(contactId, accountType)
val firstName = cursor.getString(colFirstName)?.trim()
val lastName = cursor.getString(colFamilyName)?.trim()
val middleName = cursor.getString(colMiddleName)?.trim()
if (firstName.isNullOrBlank() && lastName.isNullOrBlank() && middleName.isNullOrBlank())
continue
val contactObject = existingContact ?: ContactObject()
contactObject.firstName = firstName
contactObject.lastName = lastName
contactObject.middleName = middleName
contactIdToContactObjectMap.put(contactId, contactObject)
}
}
return contactIdToContactObjectMap
}
class ContactObject {
var firstName: String? = null
var middleName: String? = null
var lastName: String? = null
}
Usage:
thread {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
val contactIdToContactNameMap = getContactIdToContactNameMap(this)
Log.d("AppLog", "found ${contactIdToContactNameMap.size()} names for contacts")
} else Log.d("AppLog", "no contacts permission...")
}
Check here there is example code exactly for that: http://developer.android.com/guide/topics/ui/layout/listview.html
精彩评论