Android自定义联系人ListView与名称和电子邮件

问题描述 投票:0回答:1

我想从Android中的联系人构建自定义ListView信息。

Android文档在这里布局了一个非常简单的例子:https://developer.android.com/training/contacts-provider/retrieve-names#Permissions

它从您的联系人中获取显示名称,并在列表视图中显示它。给CursorLoader的投影是:

private val PROJECTION: Array<out String> = arrayOf(
    ContactsContract.Contacts._ID,
    ContactsContract.Contacts.LOOKUP_KEY,
    ContactsContract.Contacts.DISPLAY_NAME
)

然后映射到简单光标:

private val FROM_COLUMNS: Array<String> = arrayOf(
    ContactsContract.Contacts.DISPLAY_NAME
)

我还想在listview中添加一个电子邮件地址。这可能是文档使用的SimpleCursorAdapter吗?

我尝试更改投影以投影电子邮件地址:

private val PROJECTION: Array<out String> = arrayOf(
    ContactsContract.Contacts._ID,
    ContactsContract.Contacts.LOOKUP_KEY,
    ContactsContract.Contacts.DISPLAY_NAME,
    ContactsContract.CommonDataKinds.Email.DISPLAY_NAME
)

但是,当我这样做时,我得到一个例外:

java.lang.IllegalArgumentException:列数据无效4

我意识到从联系人到电子邮件的映射是一对多的。那是我的问题吗?我可以投影“主要”电子邮件地址吗?

android android-contacts simplecursoradapter
1个回答
0
投票

我不知道SimpleCursorAdapter是否可以这样做,因为我没有使用它,所以让我告诉你如何通过一个简单的查询加载电子邮件地址。

我使用以下方法同时加载电子邮件和电话号码,因此代码可能不是最佳的。

首先,电子邮件地址存储在通用ContactsContract.Data.DATA1数据列中,但同一列也可用于其他数据类型(例如,用于电话号码)。这就是我使用以下投影的原因:

private val PROJECTION =
    arrayOf(
        ContactsContract.Data.CONTACT_ID,
        ContactsContract.Data.DISPLAY_NAME_PRIMARY,
        ContactsContract.Data.DATA1,
        ContactsContract.Data.MIMETYPE
    )

然后我像下面一样查询它并逐个处理数据,每次检查data1 MIME类型:

contentResolver.query(
    ContactsContract.Data.CONTENT_URI,
    PROJECTION,
    null,
    null,
    null
)?.use { cursor ->
    val idxId = cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID)
    val idxDisplayNamePrimary = cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME_PRIMARY)
    val idxData1 = cursor.getColumnIndex(ContactsContract.Data.DATA1)
    val idxMimeType = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE)

    while (cursor.moveToNext()) {
        val id = cursor.getLong(idxId)
        val name: String? = cursor.getString(idxDisplayNamePrimary)
        val data1: String? = cursor.getString(idxData1)
        val mimeType: String? = cursor.getString(idxMimeType)

        if (mimeType == ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) {
            // e-mail was found and loaded into data1 - do something with it here
        }
    }
}

我很确定可能有更好的方法。

更新#1

一些文档在这里:

更新#2

正如您在文档或代码中看到的那样,ContactsContract.CommonDataKinds.Email.ADDRESS指向ContactsContract.Data.DATA1列。

© www.soinside.com 2019 - 2024. All rights reserved.