Android 获取联系人信息(头像、公司、手机号等)以及通话记录

AndroidManifest.xml添加声明

<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />

 先请求权限

/**
 * 请求通话记录权限
 */
@Composable
internal fun CheckPermissions(context: Context) {
    val callLogPermissions = arrayOf(
        Manifest.permission.WRITE_CALL_LOG,
        Manifest.permission.READ_CALL_LOG,
        Manifest.permission.CALL_PHONE,
        Manifest.permission.READ_CONTACTS,
        Manifest.permission.WRITE_CONTACTS,
    )
    val permissionsError = stringResource(id = R.string.permissions_error)
    val rememberLauncherForActivityResult =
        rememberLauncherForActivityResult(contract = ActivityResultContracts.RequestMultiplePermissions()) { result ->
            if (!(result[Manifest.permission.WRITE_CALL_LOG] == true || result[Manifest.permission.READ_CALL_LOG] == true || result[Manifest.permission.CALL_PHONE] == true)) {
                Toast.makeText(
                    context, permissionsError, Toast.LENGTH_LONG
                ).show()
            }
        }

    SideEffect {
        rememberLauncherForActivityResult.launch(callLogPermissions)
    }
}

获取通话记录

/**
 * 通话记录工具类
 */
object CallLogUtil {

    private val carrierMap = mapOf(
        "China Mobile" to "移动",
        "China Unicom" to "联通",
        "China Telecom" to "电信",
    )

    private val phoneNumberUtil: PhoneNumberUtil = PhoneNumberUtil.getInstance()
    private val carrierMapper: PhoneNumberToCarrierMapper = PhoneNumberToCarrierMapper.getInstance()
    private val geocoder: PhoneNumberOfflineGeocoder = PhoneNumberOfflineGeocoder.getInstance()
    private const val CHINA_LANGUAGE: String = "CN"

    /**
     * 根据号码查询通话记录
     */
    fun getCallLogByNumber(contentResolver: ContentResolver, number: String): Cursor? {
        val projection = arrayOf(
            CallLog.Calls.CACHED_NAME,
            CallLog.Calls.NUMBER,
            CallLog.Calls.DATE,
            CallLog.Calls.DURATION,
            CallLog.Calls.TYPE
        )

        val selection = "${CallLog.Calls.NUMBER} = ?"
        val selectionArgs = arrayOf(number)

        return contentResolver.query(
            CallLog.Calls.CONTENT_URI,
            projection,
            selection,
            selectionArgs,
            CallLog.Calls.DEFAULT_SORT_ORDER
        )
    }

    /**
     * 获取查询通话记录
     */
    fun getCallLog (contentResolver: ContentResolver): LinkedHashMap<String, MutableList<CallLogEntity>> {
        val linkedHashMap = linkedMapOf<String, MutableList<CallLogEntity>>()
        val columns = arrayOf(
            CallLog.Calls.CACHED_NAME,  // 通话记录的联系人
            CallLog.Calls.NUMBER,  // 通话记录的电话号码
            CallLog.Calls.DATE,  // 通话记录的日期
            CallLog.Calls.DURATION,  // 通话时长
            CallLog.Calls.TYPE // 通话类型
        )

        val cursor = contentResolver.query(
            CallLog.Calls.CONTENT_URI,
            columns,
            null,
            null,
            // 按照时间逆序排列,最近打的最先显示
            CallLog.Calls.DEFAULT_SORT_ORDER
        )

        val startTime = System.currentTimeMillis()
        var count = 0

        if (cursor != null) {
            val nameIndex = cursor.getColumnIndex(CallLog.Calls.CACHED_NAME)
            val numberIndex = cursor.getColumnIndex(CallLog.Calls.NUMBER)
            val dateIndex = cursor.getColumnIndex(CallLog.Calls.DATE)
            val durationIndex = cursor.getColumnIndex(CallLog.Calls.DURATION)
            val typeIndex = cursor.getColumnIndex(CallLog.Calls.TYPE)

            while (cursor.moveToNext() && count < 20) {
                // 姓名
                val name = cursor.getString(nameIndex)
                // 号码
                val number = cursor.getString(numberIndex)
                // 获取通话日期
                val dateLong = cursor.getLong(dateIndex)
                // 通话日期
                val date: String =
                    SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date(dateLong))
                // 通话时间
                val time: String =
                    SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date(dateLong))
                // 获取通话时长,单位:秒
                val duration = cursor.getInt(durationIndex)
                // 获取通话类型:1.呼入2.呼出3.未接
                val type = cursor.getInt(typeIndex)
                count++
                val callLogEntity = CallLogEntity(
                    number,
                    name, dateLong, date, time, getCarrier(number), getGen(number), duration, type,
                )
                // 检查手机号是否已在Map中
                if (linkedHashMap.containsKey(number)) {
                    // 如果存在,添加到现有的列表中
                    linkedHashMap[number]?.add(callLogEntity)
                } else {
                    // 如果不存在,新建列表并添加到Map中
                    linkedHashMap[number] = mutableListOf(callLogEntity)
                }
            }
        }
        val endTime = System.currentTimeMillis()
        cursor?.close()
        Log.i("TAG", "执行时间: ${endTime - startTime} ms")
        return linkedHashMap
    }

    // 初始化通话时长
    fun formatDuration(time: Long): String {
        val s = time % 60
        val m = time / 60
        val h = time / 60 / 60
        val sb = StringBuilder()
        if (h > 0) {
            sb.append(h).append("小时")
        }
        if (m > 0) {
            sb.append(m).append("分")
        }
        sb.append(s).append("秒")
        return sb.toString()
    }

    private fun getCarrier(phoneNumber: String): String {
        val referencePhoneNumber = phoneNumberUtil.parse(phoneNumber, CHINA_LANGUAGE)
        val carrierEn = carrierMapper.getNameForNumber(referencePhoneNumber, Locale.ENGLISH)
        return carrierMap[carrierEn] ?: ""
    }

    private fun getGen(phoneNumber: String): String {
        val referencePhoneNumber = phoneNumberUtil.parse(phoneNumber, CHINA_LANGUAGE)
        val descriptionForNumber =
            geocoder.getDescriptionForNumber(referencePhoneNumber, Locale.CHINA)
        return descriptionForNumber.ifBlank { "未知归属地" }
    }
}

data class CallLogEntity(
    // 手机号
    val phoneNumber: String,
    // 名称
    val name: String?,
    // 时间戳
    val timestamp: Long,
    // 日期
    val date: String,
    // 时间
    val time: String,
    // 归属地
    val belongPlace: String,
    // 运营商名称
    val netName: String,
    // 通话时长
    val duration: Int,
    // 类型
    val type: Int
)

这里需要导包,来获取运营商以及归属地信息,最好去找最新的库,要不然最近几年出的号码会显示为空。也能使用百度提供的接口获取信息

//谷歌电话号码归属地库
implementation 'com.googlecode.libphonenumber:libphonenumber:8.10.3'
implementation 'com.googlecode.libphonenumber:carrier:1.99'
implementation 'com.googlecode.libphonenumber:geocoder:2.99'
implementation 'com.googlecode.libphonenumber:prefixmapper:2.109'

获取联系人信息

/**
 * 联系人工具类
 */
object ContactPersonUtil {

    /**
     * 获取手机联系人详细信息列表
     */
    fun getContactsDetails(context: Context): MutableList<ContactPersonEntity> {
        val startTime = System.currentTimeMillis()
        val contactDetailsList = mutableListOf<ContactPersonEntity>()
        val contentResolver = context.contentResolver
        val cursor = contentResolver.query(
            ContactsContract.Contacts.CONTENT_URI,
            arrayOf(ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME),
            null,
            null,
            ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"
        )

        if (cursor != null && cursor.count > 0) {
            while (cursor.moveToNext()) {
                val contactPersonEntity = ContactPersonEntity()

                val columnIndex = cursor.getColumnIndex(ContactsContract.Contacts._ID)
                contactPersonEntity.contactId = cursor.getString(columnIndex)

                val displayNameColumn =
                    cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)
                contactPersonEntity.disPlayName = cursor.getString(displayNameColumn)

                // 获取手机号
                getPhone(contentResolver, contactPersonEntity)
                // 获取邮箱
                getEmail(contentResolver, contactPersonEntity)
                // 获取IM
                getIM(contentResolver, context, contactPersonEntity)
                // 获取地址
                getAddress(contentResolver, contactPersonEntity)
                // 获取组织
                getOrganizations(contentResolver, contactPersonEntity)
                // 获取备注
                getNote(contentResolver, contactPersonEntity)
                // 获取昵称
                getNickName(contentResolver, contactPersonEntity)
                // 获取事件
                getBirth(contentResolver, contactPersonEntity)
                // 获取网址
                getWebsites(contentResolver, contactPersonEntity)
                // 获取头像
                getAvatar(contentResolver, contactPersonEntity)
                contactDetailsList.add(contactPersonEntity)
            }
            cursor.close()
        }

        // 记录结束时间并计算耗时
        val endTime = System.currentTimeMillis()
        val duration = endTime - startTime
        Log.d("TAG", "获取联系人详情耗时:$duration 毫秒")
        return contactDetailsList
    }

    private fun getAvatar(
        contentResolver: ContentResolver,
        contactPersonEntity: ContactPersonEntity,
    ) {
        val contactUri = Uri.withAppendedPath(
            ContactsContract.Contacts.CONTENT_URI, contactPersonEntity.contactId
        )
        val iconIs = ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, contactUri)
        if (iconIs != null) {
            // 解码输入流为 Bitmap
            val bitmap = BitmapFactory.decodeStream(iconIs)
            contactPersonEntity.avatar = bitmap
            iconIs.close()
        } else {
            // 处理头像不存在的情况,比如设置默认头像
            contactPersonEntity.avatar = null
        }
    }



    private fun getWebsites(
        contentResolver: ContentResolver,
        contactPersonEntity: ContactPersonEntity,
    ) {
        val websiteList = mutableListOf<WebsiteEntity>()
        val websites = contentResolver.query(
            Data.CONTENT_URI,
            arrayOf(
                Data.DATA1, // 存储网址的列
                ContactsContract.CommonDataKinds.Website.TYPE,
                ContactsContract.CommonDataKinds.Website.LABEL
            ),
            "${Data.CONTACT_ID} = ? AND ${Data.MIMETYPE} = ?",
            arrayOf(
                contactPersonEntity.contactId.toString(),
                ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE
            ),
            null
        )

        if (websites != null && websites.moveToFirst()) {
            do {
                val websiteEntity = WebsiteEntity()

                // 获取网址URL
                val urlColumnIndex = websites.getColumnIndex(Data.DATA1)
                websiteEntity.url = websites.getString(urlColumnIndex)

                // 获取类型
                val typeIndex =
                    websites.getColumnIndex(ContactsContract.CommonDataKinds.Website.TYPE)
                val type = websites.getInt(typeIndex)

                // 获取自定义标签
                val labelIndex =
                    websites.getColumnIndex(ContactsContract.CommonDataKinds.Website.LABEL)
                val label = websites.getString(labelIndex)

                // 根据类型设置标签
                websiteEntity.type = when (type) {
                    ContactsContract.CommonDataKinds.Website.TYPE_HOMEPAGE -> "个人主页"
                    ContactsContract.CommonDataKinds.Website.TYPE_WORK -> "工作"
                    ContactsContract.CommonDataKinds.Website.TYPE_BLOG -> "博客"
                    ContactsContract.CommonDataKinds.Website.TYPE_PROFILE -> "个人资料"
                    ContactsContract.CommonDataKinds.Website.TYPE_FTP -> "FTP"
                    ContactsContract.CommonDataKinds.Website.TYPE_CUSTOM -> label ?: "自定义"
                    else -> "网址"
                }

                websiteList.add(websiteEntity)
            } while (websites.moveToNext())
        }

        contactPersonEntity.websiteEntityList = websiteList
        websites?.close()
    }


    private fun getBirth(
        contentResolver: ContentResolver,
        contactPersonEntity: ContactPersonEntity,
    ) {
        val list = mutableListOf<EventEntity>()
        // 查询条件,包括 contactId 的匹配
        val selection = contentResolver.query(
            Data.CONTENT_URI,
            arrayOf(
                Data.RAW_CONTACT_ID,
                Event.TYPE,
                Event.START_DATE,
                Data.DATA3
            ), // DATA3 用于存储自定义事件名称
            "${Event.MIMETYPE} = ? AND ${Data.RAW_CONTACT_ID} = ?",
            arrayOf(Event.CONTENT_ITEM_TYPE, contactPersonEntity.contactId.toString()),
            null
        )

        if (selection != null && selection.moveToFirst()) {
            do {
                val eventEntity = EventEntity()
                // 获取列索引
                val dateIndex = selection.getColumnIndex(Event.START_DATE)
                val eventTypeIndex = selection.getColumnIndex(Event.TYPE)
                val customLabelIndex = selection.getColumnIndex(Data.DATA3) // 获取自定义标签的索引

                // 获取事件日期和类型
                val date = selection.getString(dateIndex) ?: "无日期" // 如果没有日期则返回"无日期"
                val eventType = selection.getInt(eventTypeIndex)
                val customLabel = selection.getString(customLabelIndex) // 获取自定义标签

                // 根据类型和自定义名称确定事件描述
                val eventDescription = when (eventType) {
                    Event.TYPE_BIRTHDAY -> "生日"
                    Event.TYPE_ANNIVERSARY -> "纪念日"
                    else -> customLabel ?: "其他" // 如果自定义标签为空,则返回"其他"
                }
                eventEntity.event = eventDescription
                eventEntity.date = date
                list.add(eventEntity)
            } while (selection.moveToNext())
        }
        contactPersonEntity.eventEntityList = list
        selection?.close()
    }

    private fun getNickName(
        contentResolver: ContentResolver,
        contactPersonEntity: ContactPersonEntity,
    ) {
        val nickNameCursor = contentResolver.query(
            Data.CONTENT_URI,
            arrayOf(Data._ID, Nickname.NAME),
            "${Data.CONTACT_ID} =? AND ${Data.MIMETYPE} = '${Nickname.CONTENT_ITEM_TYPE}'",
            arrayOf(contactPersonEntity.contactId),
            null
        )

        if (nickNameCursor != null && nickNameCursor.moveToFirst()) {
            val columnIndex = nickNameCursor.getColumnIndex(Nickname.NAME)
            contactPersonEntity.nickName = nickNameCursor.getString(columnIndex)
        }

        nickNameCursor?.close()
    }

    private fun getNote(
        contentResolver: ContentResolver,
        contactPersonEntity: ContactPersonEntity,
    ) {
        val notes = contentResolver.query(
            Data.CONTENT_URI,
            arrayOf(Data._ID, Note.NOTE),
            "${Data.CONTACT_ID} =? AND ${Data.MIMETYPE} = '${Note.CONTENT_ITEM_TYPE}'",
            arrayOf(contactPersonEntity.contactId),
            null
        )
        if (notes != null && notes.moveToFirst()) {
            val columnIndex = notes.getColumnIndex(Note.NOTE)
            contactPersonEntity.noteinfo = notes.getString(columnIndex)
        }
        notes?.close()
    }

    private fun getOrganizations(
        contentResolver: ContentResolver,
        contactPersonEntity: ContactPersonEntity,
    ) {
        val organizationsList = mutableListOf<OrganizationsEntity>()
        val organizations = contentResolver.query(
            Data.CONTENT_URI,
            arrayOf(Data._ID, Organization.COMPANY, Organization.TITLE),
            "${Data.CONTACT_ID} =? AND ${Data.MIMETYPE} = '${Organization.CONTENT_ITEM_TYPE}'",
            arrayOf(contactPersonEntity.contactId),
            null
        )
        if (organizations != null && organizations.moveToFirst()) {
            do {
                val organizationsEntity = OrganizationsEntity()
                val companyColumnIndex = organizations.getColumnIndex(Organization.COMPANY)
                val titleColumnIndex = organizations.getColumnIndex(Organization.TITLE)
                organizationsEntity.company = organizations.getString(companyColumnIndex)
                organizationsEntity.title = organizations.getString(titleColumnIndex)
                organizationsList.add(organizationsEntity)
            } while (organizations.moveToNext())
        }
        contactPersonEntity.organizationsEntityList = organizationsList
        organizations?.close()
    }

    /**
     * 获取联系人地址
     */
    private fun getAddress(
        contentResolver: ContentResolver,
        contactPersonEntity: ContactPersonEntity,
    ) {
        val addressList = mutableListOf<AddressEntity>()
        val address = contentResolver.query(
            ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,
            null,
            "${ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID} = ?",
            arrayOf(contactPersonEntity.contactId),
            null
        )

        if (address != null && address.moveToFirst()) {
            do {
                val streetColumnIndex =
                    address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET)
                val cityColumnIndex =
                    address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY)
                val regionColumnIndex =
                    address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION)
                val postcodeColumnIndex =
                    address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE)
                val formattedAddColumnIndex =
                    address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS)
                val typeIndex =
                    address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.TYPE)
                val labelIndex =
                    address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.LABEL)

                val addressEntity = AddressEntity()
                addressEntity.street = address.getString(streetColumnIndex)
                addressEntity.city = address.getString(cityColumnIndex)
                addressEntity.region = address.getString(regionColumnIndex)
                addressEntity.postcode = address.getString(postcodeColumnIndex)
                addressEntity.formatted = address.getString(formattedAddColumnIndex)

                // 获取类型索引
                val type = address.getInt(typeIndex)

                // 根据类型设置标签
                addressEntity.type = when (type) {
                    ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME -> "住宅"
                    ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK -> "单位"
                    ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER -> "其他"
                    ContactsContract.CommonDataKinds.StructuredPostal.TYPE_CUSTOM -> {
                        // 获取自定义标签
                        address.getString(labelIndex) ?: "自定义"
                    }

                    else -> "未知" // 如果类型未识别
                }

                addressList.add(addressEntity)
            } while (address.moveToNext())
        }

        contactPersonEntity.addressEntityList = addressList
        address?.close()
    }

    /**
     * 获取IM
     */
    private fun getIM(
        contentResolver: ContentResolver,
        context: Context,
        contactPersonEntity: ContactPersonEntity,
    ) {
        val imList = mutableListOf<IMEntity>()
        val ims = contentResolver.query(
            Data.CONTENT_URI,
            arrayOf(Data._ID, Im.PROTOCOL, Im.CUSTOM_PROTOCOL, Im.DATA),
            "${Data.CONTACT_ID} = ? AND ${Data.MIMETYPE} = '${Im.CONTENT_ITEM_TYPE}'",
            arrayOf(contactPersonEntity.contactId),
            null
        )

        if (ims != null && ims.moveToFirst()) {
            do {
                val imEntity = IMEntity()
                val protocolColumnIndex = ims.getColumnIndex(Im.PROTOCOL)
                val customProtocolColumnIndex = ims.getColumnIndex(Im.CUSTOM_PROTOCOL)
                val dataColumnIndex = ims.getColumnIndex(Im.DATA)

                val protocol = ims.getInt(protocolColumnIndex)
                val protocolString: String? = if (protocol == Im.PROTOCOL_CUSTOM) {
                    // 自定义协议
                    ims.getString(customProtocolColumnIndex) 
                } else {
                    // 标准协议
                    Im.getProtocolLabel(context.resources, protocol, null)
                        ?.toString() 
                }
                // 如果为空则分配默认值
                imEntity.imType = protocolString ?: "Unknown" 
                imEntity.imNumber = ims.getString(dataColumnIndex)
                imList.add(imEntity)
            } while (ims.moveToNext())
        }
        contactPersonEntity.imEntityList = imList
        ims?.close()
    }


    /**
     * 获取邮箱
     */
    private fun getEmail(
        contentResolver: ContentResolver,
        contactPersonEntity: ContactPersonEntity,
    ) {
        val emailList = mutableListOf<EmailEntity>()
        val emails = contentResolver.query(
            ContactsContract.CommonDataKinds.Email.CONTENT_URI,
            null,
            "${ContactsContract.CommonDataKinds.Email.CONTACT_ID} = ?",
            arrayOf(contactPersonEntity.contactId),
            null
        )

        if (emails != null && emails.moveToFirst()) {
            do {
                val emailEntity = EmailEntity()
                val emailTypeIndex =
                    emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE)
                val emailDataIndex =
                    emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)
                val labelIndex = emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.LABEL)

                // 获取邮箱类型
                val type = emails.getInt(emailTypeIndex)

                // 根据类型设置标签
                emailEntity.emailType = when (type) {
                    ContactsContract.CommonDataKinds.Email.TYPE_HOME -> "个人"
                    ContactsContract.CommonDataKinds.Email.TYPE_WORK -> "单位"
                    ContactsContract.CommonDataKinds.Email.TYPE_OTHER -> "其他"
                    ContactsContract.CommonDataKinds.Email.TYPE_CUSTOM -> {
                        // 获取自定义标签
                        emails.getString(labelIndex) ?: "自定义"
                    }

                    else -> "未知" // 如果类型未识别
                }

                // 获取邮箱地址
                emailEntity.emailData = emails.getString(emailDataIndex)

                emailList.add(emailEntity)
            } while (emails.moveToNext())
        }

        contactPersonEntity.emailEntityList = emailList
        emails?.close()
    }


    /**
     * 获取联系人手机号
     */
    private fun getPhone(
        contentResolver: ContentResolver,
        contactPersonEntity: ContactPersonEntity,
    ) {
        val phones = contentResolver.query(
            Phone.CONTENT_URI,
            null,
            "${Phone.CONTACT_ID} = ?",
            arrayOf(contactPersonEntity.contactId),
            null
        )
        val phoneTypeList = mutableListOf<PhoneEntity>()
        if (phones != null && phones.moveToFirst()) {
            do {
                val phoneTypeEntity = PhoneEntity()

                // 获取电话类型
                val phoneTypeColumnIndex = phones.getColumnIndex(Phone.TYPE)
                val phoneType = if (phoneTypeColumnIndex != -1) {
                    phones.getInt(phoneTypeColumnIndex)
                } else {
                    // 如果找不到类型,则默认为移动设备
                    Phone.TYPE_MOBILE
                }

                // 获取电话号码
                val phoneNumberColumnIndex = phones.getColumnIndex(Phone.NUMBER)
                if (phoneNumberColumnIndex != -1) {
                    val phoneNumber = phones.getString(phoneNumberColumnIndex)
                    phoneTypeEntity.phoneNumber = phoneNumber
                }

                // 根据类型设置标签
                phoneTypeEntity.phoneType = when (phoneType) {
                    Phone.TYPE_HOME -> "住宅"
                    Phone.TYPE_WORK -> "单位"
                    Phone.TYPE_FAX_WORK -> "单位传真"
                    Phone.TYPE_FAX_HOME -> "住宅传真"
                    Phone.TYPE_PAGER -> "寻呼机"
                    Phone.TYPE_CALLBACK -> "回拨号码"
                    Phone.TYPE_COMPANY_MAIN -> "公司总机"
                    Phone.TYPE_CAR -> "车载电话"
                    Phone.TYPE_ISDN -> "ISDN"
                    Phone.TYPE_MAIN -> "总机"
                    Phone.TYPE_RADIO -> "无线装置"
                    Phone.TYPE_TELEX -> "电报"
                    Phone.TYPE_TTY_TDD -> "TTY_TDD"
                    Phone.TYPE_WORK_MOBILE -> "单位手机"
                    Phone.TYPE_WORK_PAGER -> "单位寻呼机"
                    Phone.TYPE_ASSISTANT -> "助理"
                    Phone.TYPE_MMS -> "彩信"
                    else -> "手机"
                }

                phoneTypeList.add(phoneTypeEntity)
            } while (phones.moveToNext())
        }
        contactPersonEntity.phoneEntityList = phoneTypeList
        phones?.close()
    }

    /**
     * 联系人手机实体
     */
    data class PhoneEntity(
        var phoneType: String? = "",
        var phoneNumber: String? = "",
    )

    /**
     * 联系人IM
     */
    data class IMEntity(
        var imType: String? = "",
        var imNumber: String? = "",
    )

    /**
     * 联系人IM
     */
    data class EmailEntity(
        var emailType: String? = "",
        var emailData: String? = "",
    )

    /**
     * 联系人地址
     */
    data class AddressEntity(
        var street: String? = "",
        var city: String? = "",
        var region: String? = "",
        var postcode: String? = "",
        var formatted: String? = "",
        var type: String? = "",
    )

    /**
     * 联系人组织
     */
    data class OrganizationsEntity(
        var company: String? = "",
        var title: String? = "",
    )

    /**
     * 联系人事件
     */
    data class EventEntity(
        var event: String? = "",
        var date: String? = "",
    )

    /**
     * 联系人网址
     */
    data class WebsiteEntity(
        var url: String? = "",
        var type: String? = "",
    )

    /**
     * 联系人实体
     */
    data class ContactPersonEntity(
        var contactId: String = "",
        // 名称
        var disPlayName: String? = "",
        // 备注
        var noteinfo: String? = "",
        // 昵称
        var nickName: String? = "",
        var avatar: Bitmap? = null,
        var phoneEntityList: MutableList<PhoneEntity> = mutableListOf(),
        var imEntityList: MutableList<IMEntity> = mutableListOf(),
        var emailEntityList: MutableList<EmailEntity> = mutableListOf(),
        var addressEntityList: MutableList<AddressEntity> = mutableListOf(),
        var organizationsEntityList: MutableList<OrganizationsEntity> = mutableListOf(),
        var eventEntityList: MutableList<EventEntity> = mutableListOf(),
        var websiteEntityList: MutableList<WebsiteEntity> = mutableListOf(),
    )
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值