23

如何从 Android 联系人中获取以下字段?我用的是安卓 2.2。

  1. 名称前缀
  2. 中间名字
  3. 名称前缀
  4. 拼音名字
  5. 拼音中间名
  6. 拼音姓氏
4

9 回答 9

58

ContactsContract.CommonDataKinds.StructuredName课。您可以在那里找到您正在寻找的所有列。像这样尝试:

    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();

它返回联系人中的所有姓名。更准确地说,您可以将联系人 ID 作为附加参数添加到查询中 - 您将获得特定联系人的地址。

于 2011-01-04T23:22:55.903 回答
17

对于指定的联系人,您可以这样做:

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();
于 2012-06-15T09:18:57.993 回答
7

作为另一个示例(只是为了好玩),但用于获取单个用户的联系人姓名:

// 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();
于 2013-03-15T13:18:15.087 回答
7

尝试使用此代码获取有关联系人的所需信息,代码在这里-

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");
于 2012-10-27T06:39:56.553 回答
1

ContactsContract.Data.CONTENT_URI2015 年底在棉花糖上试验。我无法获得GIVEN_NAME或类似的领域。我认为后来的 api 已经弃用了这些。运行以下代码以打印出您手机上的列

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");
  }
}
于 2015-12-27T07:18:29.183 回答
0

尝试这个,

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());
    }
}
于 2016-02-15T06:33:29.450 回答
0

在这里结合各种解决方案,并看到结果中有重复记录(由于多个帐户),我决定创建一个函数,将常见帐户类型优先于其他帐户类型。在这个示例中,我也忽略了完全为空/空名称的记录(如果都是这样的话),但如果您愿意,您可以更改它:

@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
}

用法:

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...")
}
于 2021-02-28T09:27:32.090 回答
-2

检查这里有完全适用的示例代码:http: //developer.android.com/guide/topics/ui/layout/listview.html

于 2015-03-13T09:40:58.130 回答