Android使用ez-vcard导出VCard时URISyntaxException报错如何解决?
问题根因
报错Expected scheme name at index 0: :的本质是ez-vcard的Impp构造逻辑会把传入的协议类型和账号值拼接为[scheme]:[value]格式的URI,当出现以下任意一种情况时,就会生成不符合URI规范的字符串触发异常:
mIM.value为空,拼接后会得到[scheme]:,scheme后无有效内容- 走else分支时
mLabel为空,拼接后会得到:[value],开头没有合法scheme - 自定义
mLabel包含中文、空格、特殊符号,不符合URI scheme的命名规范
解决方案
1. 增加前置非空校验
遍历IM项时先判断账号值是否为空,为空直接跳过该条无效数据,不需要后续构造逻辑:
contact.IMs.forEach {mIM-> // 新增:账号值为空直接跳过 if (mIM.value.isNullOrEmpty()) { return@forEach } try { val mLabel = if(mIM.label.isNullOrEmpty()) mIM.value else mIM.label val impp = when (mIM.type) { ContactsContract.CommonDataKinds.Im.PROTOCOL_AIM -> Impp.aim(mIM.value) ContactsContract.CommonDataKinds.Im.PROTOCOL_YAHOO -> Impp.yahoo(mIM.value) ContactsContract.CommonDataKinds.Im.PROTOCOL_MSN -> Impp.msn(mIM.value) ContactsContract.CommonDataKinds.Im.PROTOCOL_ICQ -> Impp.icq(mIM.value) ContactsContract.CommonDataKinds.Im.PROTOCOL_SKYPE -> Impp.skype(mIM.value) ContactsContract.CommonDataKinds.Im.PROTOCOL_GOOGLE_TALK -> Impp(HANGOUTS, mIM.value) ContactsContract.CommonDataKinds.Im.PROTOCOL_QQ -> Impp(QQ, mIM.value) ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER -> Impp(JABBER, mIM.value) else -> { // 校验label是否为合法的URI scheme(只能包含字母、数字、+、-、.) val validScheme = mLabel.takeIf { it.matches(Regex("[a-zA-Z0-9+\\-.]+")) } ?: "x-custom-im" // 不符合就用默认自定义scheme Impp(validScheme, mIM.value) } } card.addImpp(impp) }catch (e: Exception){ // 补充空状态日志方便排查 crashlytics.setCustomKey("IM value empty", mIM.value.isNullOrEmpty()) crashlytics.setCustomKey("IM label empty", mIM.label.isNullOrEmpty()) crashlytics.setCustomKey("Contact IMs", "Label: "+mIM.label+" Value: "+mIM.value+" Type: "+mIM.type) Applog.e(TAG, e) } }
2. 可选优化:升级ez-vcard版本
你当前使用的0.11.3是2020年的旧版本,最新稳定版已经对部分非法输入做了兼容处理,非必要场景下可以升级降低异常概率。
内容的提问来源于stack exchange,提问作者Sagar Maiyad
相关产品推荐
相关产品推荐

