android导入vCard联系人流程
来源:互联网 发布:lk在linux的哪一层 编辑:程序博客网 时间:2024/06/15 17:57
本博客基于android7.1版本分析,仅用于沟通学习使用
上一篇博客介绍了 android导出vCard联系人流程 紧接着我们在这篇博客来看看它是如何导入一个vCard联系人的。
整体流程总结
- 通过在contacts联系人中界面跳转,我们跳转到了 DocumentsActivity 界面并选择我们需要导入的以 .vcf 结尾的vCard文件,将Uri以intent的方式返回给ImportVCardActivity。
- 通过readUriToLocalUri方法将uri指向的文件copy到本地临时目录。
- 启动一个线程开始解析文件,并指定vCard类型为 text/x-vcard 版本为2.1,后面就只会创建2.1版本对应的解析器,所以其它版本的vCard导入可能会出现问题。
- 然后通过VCardParserImpl_V21来具体解析文件中的每一行,最后通过VCardEntryCommitter.pushIntoContentResolver批量插入contacts的数据库
几个重点类的作用
- ImportVCardActivity : 一个中间控制类,它控制了界面dialog、notification、service、thread的启动和消失
- VCardParserImpl_V21 : 负责vCard2.1版本内容的逐行解析
- VCardEntryConstructor : 负责将解析出来的数据以VCardEntry的形式暂存在内存中
- VCardEntryCommitter : 负责将解析出来的数据存储到contacts数据库中
整体操作图
整体流程图
部分重点方法介绍
VCardParserImpl_V21
/** * <code> * vcard = "BEGIN" [ws] ":" [ws] "VCARD" [ws] 1*CRLF * items *CRLF * "END" [ws] ":" [ws] "VCARD" * </code> * @return False when reaching end of file. */ private boolean parseOneVCard() throws IOException, VCardException { // reset for this entire vCard. mCurrentEncoding = DEFAULT_ENCODING; //8BIT mCurrentCharset = DEFAULT_CHARSET; //UTF-8 boolean 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:vCard if (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 + "\""); } }
阅读全文
0 0
- android导入vCard联系人流程
- android导出vCard联系人流程
- Android VCard联系人备份恢复(导入/导出)详解
- Android VCard联系人备份恢复(导入/导出)详解
- vCard(.vcf)文件批量导入Gmail联系人的快速方法
- VCard联系人备份恢复(导入/导出)详解
- Android VCard通讯录导入导出详解
- Android中联系人导入
- 开机导入Sim卡联系人流程分析
- Android 使用VCard数据类型 异步进行联系人备份与恢复操作
- Android 手机 联系人导入方法
- Android,通讯录导入,contacts,联系人
- android系统联系人查询流程
- 代码实现添加联系人——Vcard
- android 使用vcard示例
- Android中使用VCard
- android 使用vcard示例
- android 使用vcard示例
- ActiveMQ中遇到的问题
- Linux进程间通信——管道
- 构造,拷贝构造的N种调用情况
- codeforces876B
- 解决虚拟机CentOS7虚拟机无法上网
- android导入vCard联系人流程
- 【图像处理】人眼区域分割(1)
- 自定义Selector篇,改变样式,绘制图案和背景
- SQL 中replace函数的用法
- 正质因数分解
- [分治 Floyd] 计蒜之道2016复赛 .百度地图的实时路况
- 7 场 AI 技术专题,开发者必看!
- Java集合——HashMap
- 数据结构之顺序表应用-----《约瑟夫问题》