热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android导入vCard联系人流程

本博客基于android7.1版本分析,仅用于沟通学习使用上一篇博客介绍了android导出vCard联系人流程紧接着我们在这篇博客来看看它是如何导入一个vCard

本博客基于android7.1版本分析,仅用于沟通学习使用

上一篇博客介绍了 android导出vCard联系人流程 紧接着我们在这篇博客来看看它是如何导入一个vCard联系人的。


整体流程总结


  1. 通过在contacts联系人中界面跳转,我们跳转到了 DocumentsActivity 界面并选择我们需要导入的以 .vcf 结尾的vCard文件,将Uri以intent的方式返回给ImportVCardActivity。
  2. 通过readUriToLocalUri方法将uri指向的文件copy到本地临时目录。
  3. 启动一个线程开始解析文件,并指定vCard类型为 text/x-vcard 版本为2.1,后面就只会创建2.1版本对应的解析器,所以其它版本的vCard导入可能会出现问题。
  4. 然后通过VCardParserImpl_V21来具体解析文件中的每一行,最后通过VCardEntryCommitter.pushIntoContentResolver批量插入contacts的数据库

几个重点类的作用


  • ImportVCardActivity : 一个中间控制类,它控制了界面dialog、notification、service、thread的启动和消失
  • VCardParserImpl_V21 : 负责vCard2.1版本内容的逐行解析
  • VCardEntryConstructor : 负责将解析出来的数据以VCardEntry的形式暂存在内存中
  • VCardEntryCommitter : 负责将解析出来的数据存储到contacts数据库中

整体操作图

这里写图片描述


整体流程图

这里写图片描述


部分重点方法介绍


VCardParserImpl_V21

/*** * vcard = "BEGIN" [ws] ":" [ws] "VCARD" [ws] 1*CRLF* items *CRLF* "END" [ws] ":" [ws] "VCARD"* * @return False when reaching end of file.*/private boolean parseOneVCard() throws IOException, VCardException {// reset for this entire vCard.mCurrentEncoding = DEFAULT_ENCODING; //8BITmCurrentCharset = DEFAULT_CHARSET; //UTF-8boolean allowGarbage = false;if (!readBeginVCard(allowGarbage)) {return false;}for (VCardInterpreter interpreter : mInterpreterList) {interpreter.onEntryStarted(); //解析vCard中一个联系人开始标志}parseItems();//逐行解析for (VCardInterpreter interpreter : mInterpreterList) {interpreter.onEntryEnded(); //解析完vCard中一个联系人结束标志}return true;}

protected boolean readBeginVCard(boolean allowGarbage) throws IOException, VCardException {// TODO: use consructPropertyLine().String line;do {while (true) {line = getLine();if (line == null) {return false;} else if (line.trim().length() > 0) {break;}}final String[] strArray = line.split(":", 2);final int length = strArray.length;// Although vCard 2.1/3.0 specification does not allow lower cases,// we found vCard file emitted by some external vCard expoter have such// invalid Strings.// e.g. BEGIN:vCardif (length == 2 && strArray[0].trim().equalsIgnoreCase("BEGIN")&& strArray[1].trim().equalsIgnoreCase("VCARD")) { //判断是否是开头?return true;} else if (!allowGarbage) {throw new VCardException("Expected String \"BEGIN:VCARD\" did not come "+ "(Instead, \"" + line + "\" came)");}} while (allowGarbage);throw new VCardException("Reached where must not be reached.");}

/** item = [groups "."] name [params] ":" value CRLF / [groups "."] "ADR"* [params] ":" addressparts CRLF / [groups "."] "ORG" [params] ":" orgparts* CRLF / [groups "."] "N" [params] ":" nameparts CRLF / [groups "."]* "AGENT" [params] ":" vcard CRLF*/protected boolean parseItem() throws IOException, VCardException {// Reset for an item.mCurrentEncoding = DEFAULT_ENCODING;final String line = getNonEmptyLine();final VCardProperty propertyData = constructPropertyData(line);final String propertyNameUpper = propertyData.getName().toUpperCase();final String propertyRawValue = propertyData.getRawValue();if (propertyNameUpper.equals(VCardConstants.PROPERTY_BEGIN)) {if (propertyRawValue.equalsIgnoreCase("VCARD")) {handleNest();} else {throw new VCardException("Unknown BEGIN type: " + propertyRawValue);}} else if (propertyNameUpper.equals(VCardConstants.PROPERTY_END)) {if (propertyRawValue.equalsIgnoreCase("VCARD")) {return true; // Ended.} else {throw new VCardException("Unknown END type: " + propertyRawValue);}} else {parseItemInter(propertyData, propertyNameUpper);}return false;}

private void parseItemInter(VCardProperty property, String propertyNameUpper)throws IOException, VCardException {String propertyRawValue = property.getRawValue();if (propertyNameUpper.equals(VCardConstants.PROPERTY_AGENT)) {handleAgent(property);} else if (isValidPropertyName(propertyNameUpper)) {if (propertyNameUpper.equals(VCardConstants.PROPERTY_VERSION) &&!propertyRawValue.equals(getVersionString())) {throw new VCardVersionException("Incompatible version: " + propertyRawValue + " != " + getVersionString());}handlePropertyValue(property, propertyNameUpper); //解析里面每个属性} else {throw new VCardException("Unknown property name: \"" + propertyNameUpper + "\"");}}

推荐阅读
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • {moduleinfo:{card_count:[{count_phone:1,count:1}],search_count:[{count_phone:4 ... [详细]
  • 本篇文章笔者在上海吃饭的时候突然想到的这段时间就有想写几篇关于返回系统的笔记,所以回家到之后就奋笔疾书的写出来发布了事先在网上找了很多方法,发现有 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 在编写业务代码时,常常会遇到复杂的业务逻辑导致代码冗长混乱的情况。为了解决这个问题,可以利用中间件模式来简化代码逻辑。中间件模式可以帮助我们更好地设计架构和代码,提高代码质量。本文介绍了中间件模式的基本概念和用法。 ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • Android源码中的Builder模式及其作用
    本文主要解释了什么是Builder模式以及其作用,并结合Android源码来分析Builder模式的实现。Builder模式是将产品的设计、表示和构建进行分离,通过引入建造者角色,简化了构建复杂产品的流程,并且使得产品的构建可以灵活适应变化。使用Builder模式可以解决开发者需要关注产品表示和构建步骤的问题,并且当构建流程发生变化时,无需修改代码即可适配新的构建流程。 ... [详细]
  • 第一步:PyQt4Designer设计程序界面该部分设计类同VisvalStudio内的设计,改下各部件的objectName!设计 ... [详细]
  • 转载:MFC 获得各类指针、句柄的方法
    2019独角兽企业重金招聘Python工程师标准转载:最近有些人在问MFC编程一些要点,有一些句柄的获取、指针的获取是 ... [详细]
author-avatar
右心1477
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有