【问题标题】:Android custom contacts ListView with name and email带有姓名和电子邮件的 Android 自定义联系人 ListView
【发布时间】:2019-08-26 14:48:07
【问题描述】:

我想在 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
)

我还想在列表视图中添加一个电子邮件地址。这可以通过文档使用的 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】:

    我不知道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 列。

    【讨论】:

      猜你喜欢
      • 2014-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-02
      • 1970-01-01
      • 2022-07-15
      • 1970-01-01
      相关资源
      最近更新 更多