Android ContactsContract调用ACTION_INSERT时部分联系人字段未保存
问题原因
你的代码核心问题是对ACTION_INSERT隐式Intent的Extra传参规则理解错了:
- 只有
ContactsContract.Intents.Insert类中明确定义的Extra常量,才能被系统自带的联系人添加页面识别并写入,你直接使用CommonDataKinds下各子类的字段常量作为Extra Key,这些Key不在系统联系人页的解析范围内,自然不会被保存。 - 第二个
.apply{}块完全没有存在的意义:Intent的Extra存储在Bundle结构中,相同Key传入的值会被后写入的内容直接覆盖,你在第二个块里用和第一个块完全相同的StructuredPostal、Event相关Key传值,直接把之前填的家庭地址、生日参数覆盖成了工作地址、纪念日,而且这些Key本身就不被支持,相当于无效操作。
具体字段写入失败的对应原因
你可以对照下成功写入的字段,全都是Intents.Insert里明确定义过的Extra:3组电话对应PHONE/SECONDARY_PHONE/TERTIARY_PHONE,2组邮箱对应EMAIL/SECONDARY_EMAIL,加上NAME/COMPANY/JOB_TITLE/NOTES,这些都在官方支持的传参列表里,所以能正常保存。剩下的字段失败原因分别是:
- 称谓前缀、称谓后缀、昵称、网站地址:
Intents.Insert没有定义对应这些字段的Extra常量,你直接拿StructuredName/Nickname/Website类下的字段名当Key传参,系统页面不会解析。 - 家庭/工作地址、生日/纪念日:首先
Intents.Insert仅支持传入1组邮政地址、1组事件数据,根本没提供第二组地址、第二组事件的传参常量;其次你直接用StructuredPostal/Event的字段常量当Key,本身就不在支持列表里,哪怕只传1组也存不上。 - IM账号及类型:虽然
Intents.Insert里定义了IM_HANDLE和IM_PROTOCOL两个常量,但大量定制安卓ROM的系统联系人应用对这组参数做了裁剪,会直接忽略这两个字段,兼容性极差。
解决方案
如果你需要写入全量的联系人字段,不要用隐式Intent跳转系统添加页的方式:
- 直接通过
ContentResolver操作ContactsContract.RawContacts.CONTENT_URI做批量事务写入,这种方式不受系统联系人页面的传参限制,可以写入所有CommonDataKinds支持的字段,也能同时存储多组地址、多组纪念日、昵称、前后缀、IM、网站等任意你需要的内容。 - 写入完成后,你可以再根据返回的联系人Uri跳转到系统联系人详情页,体验和直接跳转添加页没有区别。
如果你坚持使用
ACTION_INSERT隐式跳转的方案,只能传入ContactsContract.Intents.Insert文档中列出的有限个Extra,未列出的字段都无法传递,也没法同时传入两组地址、两个日期类字段。
内容的提问来源于stack exchange,提问作者Marvil
相关产品推荐
相关产品推荐

