当前位置: 首页 > news >正文

【android bluetooth 协议分析 18】【PBAP详解 2】【车机为何不显示电话号码为空的联系人信息】

一、问题描述

在苹果手机中, 会将 只有名字,没有电话号码的 vcard 传到 车机侧。 但是应用侧确显示不出来。针对这个问题,我们深入探讨一下,究竟是谁把他给过滤掉了。

下面的log 是从 btsnoop 中导出的。

BEGIN:VCARD
VERSION:3.0
FN:空号测试
N:空号测试
TEL:
END:VCARDBEGIN:VCARD
VERSION:3.0
FN:Konghao 
N:Konghao 
TEL:
END:VCARD

备注:

  • 但是用其他手机, 例如 IQOO Nevo 3E 上述 vcard 并不会 通过蓝牙 传递到 车机侧, 只有 苹果手机会传。

二、源码回溯

当车机解析手机传递过来的 vcard 时, 将触发 VCardEntry.java::addProperty. 调用流程可以参考 【android bluetooth 协议分析 18】【PBAP详解 1】【为何我们的通话记录中会出现1-521-8xx-1x9x】 这里不再重复。

  • android/frameworks/opt/vcard/java/com/android/vcard/VCardEntry.java
public void addProperty(final VCardProperty property) {final String propertyName = property.getName();final Map<String, Collection<String>> paramMap = property.getParameterMap();final List<String> propertyValueList = property.getValueList();byte[] propertyBytes = property.getByteValue();if ((propertyValueList == null || propertyValueList.size() == 0)&& propertyBytes == null) {return;}final String propValue = (propertyValueList != null? listToString(propertyValueList).trim(): null);if (propertyName.equals(VCardConstants.PROPERTY_VERSION)) {// vCard version. Ignore this.} else if (propertyName.equals(VCardConstants.PROPERTY_FN)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_NAME)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_N)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_SORT_STRING)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_NICKNAME)|| propertyName.equals(VCardConstants.ImportOnly.PROPERTY_X_NICKNAME)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_SOUND)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_ADR)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_EMAIL)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_ORG)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_TITLE)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_ROLE)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_PHOTO)|| propertyName.equals(VCardConstants.PROPERTY_LOGO)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_TEL)) {String phoneNumber = null;boolean isSip = false;if (VCardConfig.isVersion40(mVCardType)) {...} else {phoneNumber = propValue;}if (isSip) {...} else {if (propValue.length() == 0) {return; // 这里当 TEL 标签 空时,直接返回了。 这里直接将 TEL 为空的联系人给过滤掉了。}final Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);final Object typeObject = VCardUtils.getPhoneTypeFromStrings(typeCollection,phoneNumber);final int type;final String label;if (typeObject instanceof Integer) {type = (Integer) typeObject;label = null;} else {type = Phone.TYPE_CUSTOM;label = typeObject.toString();}final boolean isPrimary;if (typeCollection != null &&typeCollection.contains(VCardConstants.PARAM_TYPE_PREF)) {isPrimary = true;} else {isPrimary = false;}addPhone(type, phoneNumber, label, isPrimary);}} else if (propertyName.equals(VCardConstants.PROPERTY_X_SKYPE_PSTNNUMBER)) {...} else if (sImMap.containsKey(propertyName)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_NOTE)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_URL)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_BDAY)) {mBirthday = new BirthdayData(propValue);} else if (propertyName.equals(VCardConstants.PROPERTY_ANNIVERSARY)) {mAnniversary = new AnniversaryData(propValue);} else if (propertyName.equals(VCardConstants.PROPERTY_X_PHONETIC_FIRST_NAME)) {mNameData.mPhoneticGiven = propValue;} else if (propertyName.equals(VCardConstants.PROPERTY_X_PHONETIC_MIDDLE_NAME)) {mNameData.mPhoneticMiddle = propValue;} else if (propertyName.equals(VCardConstants.PROPERTY_X_PHONETIC_LAST_NAME)) {mNameData.mPhoneticFamily = propValue;} else if (propertyName.equals(VCardConstants.PROPERTY_IMPP)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_X_SIP)) {...} else if (propertyName.equals(VCardConstants.PROPERTY_X_ANDROID_CUSTOM)) {...} else if (propertyName.toUpperCase().startsWith("X-")) {...} else {}// Be careful when adding some logic here, as some blocks above may use "return".}

return 注释掉后, 电话号码为空的联系人,也可以正常在车机进行显示了。

http://www.dtcms.com/a/548590.html

相关文章:

  • MacPro2012升级Monterey终极解决方案
  • 软件项目管理工具
  • Actix Web适合什么类型的Web应用?可以部署 Java 或 .NET 的应用程序?
  • Android PDF 操作 - AndroidPdfViewer 弹出框显示 PDF
  • 做新零售这些注册网站和找货源6内蒙古网站建设流程
  • 【Linux篇】进程间通信 - 匿名管道
  • Java Stream Collectors主要 API 详解
  • Mac如何安装mysql和完全卸载mysql
  • 【Docker】【03.使用docker搭建ubuntu20.04 Qt5.12 开发环境】
  • uni-app 上架 iOS 应用全流程 从云打包到开心上架(Appuploader)免 Mac 上传发布指南
  • 深圳公司网站设计公司wordpress春菜
  • 广东省省考备考(第一百三十七天10.30)——资料分析、数量关系(强化训练)
  • 【SpringMVC】SpringMVC 小案例:加法计算器初步理解前后端接口交互与数据处理
  • 微软全球服务中断:Azure、365、Xbox及Minecraft等多平台受影响
  • 【QT常用技术讲解】可拖拽文件的Widget--QListWidget
  • 手机网站标准家政公司怎么注册
  • 上海网站建设500元wordpress在线支付表单
  • 厦门市小学生信息学竞赛(C++)初赛总复习(第二章 算法知识与数据结构 -第二节 数据结构 第三节 栈)
  • 【OD刷题笔记】- 5G网络建设
  • 基于毫米波雷达的汽车变道辅助系统(LCA)原理与实现
  • 赋能智慧货运:视频汇聚平台EasyCVR打造货运汽车安全互联网视频监控与管理方案
  • 数图科技赋能长春欧亚:构建零售 “智慧大脑”,让陈列调整、决策响应快人一步
  • MongoDB 正则表达式
  • 【超级详细】正点原子RK3588安装和编译SDK
  • AI 图像生成技术发展时间脉络:从 GAN 到多模态大模型的知名模型概略解析
  • “一网通办”查询响应优化:金仓索引如何支撑政务高效服务
  • 微信小程序(H5)上传文件到阿里云 OSS(使用 STS 临时凭证)
  • 建设局网站打不开是什么原因先做网站先备案
  • Bootstrap 按钮
  • Qt 外观之Qt样式表(QSS)