VCard联系人备份恢复(导入/导出)详解

2023-10-24 12:10

本文主要是介绍VCard联系人备份恢复(导入/导出)详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章摘自:http://www.cnblogs.com/lw900320/archive/2013/01/10/2855145.html

首先我们简单的看下在Android中联系人的存储结构.

工作环境:android 2.3.3
联系人的主要数据存放在raw_contacts和data表里,它两构成主从表关系。

raw_contacts表结构:

data表结构:

每个联系人在raw_contacts里有一条记录,像地址,名称,email,电话等等数据都在data存放在data里,这样设计的好处是易扩展,比如要增加一个联系人的email地址时,只要在data里增加一条记录。

下面说说我在开发工作中用到的一些联系人的数据。

名字:

Uri: Uri.parse("content://com.android.contacts/data")

PREFIX = "data4"; //名称前缀
MID_NAME = "data5";//中间名
GIVEN_NAME = "data2";//名字
FAMILY_NAME = "data3";//姓氏
MID_PINYIN="data8"; //中间名拼音
String FAMILY_NAME_PINYIN="data9"; //姓氏拼音
String SUFIX = "data6"; //名称后缀
String SUFIX_PINYIN="data7"; //名字拼音

电话:

Uri: Uri.parse("content://com.android.contacts/data/phones"

phone: "data1";//号码

Type: "data2";//这个字段是整形值,指示电话类型

类型对应关系如下:

TYPE_CUSTOM = 0;
TYPE_HOME = 1;
TYPE_MOBILE = 2;
TYPE_WORK = 3;
TYPE_FAX_WORK = 4;
TYPE_FAX_HOME = 5;
TYPE_PAGER = 6;
TYPE_OTHER = 7;

 

Email:

 

Uri:Uri.parse("content://com.android.contacts/data/emails")

Email: "data1";//邮箱地址

Type: "data2";//这个字段是整形值,指示Email类型

类型对应关系如下:

TYPE_CUSTOM = 0;
TYPE_HOME = 1;
TYPE_WORK = 2;
TYPE_OTHER = 3;
TYPE_MOBILE = 4;

 

地址:

Uri:Uri.parse("content://com.android.contacts/data/postals")

STREET="data4";//街道
CITY="data8";//城市
STATE="data7";//州
ZIP_CODE="data9";//邮政编码

Type:"data2";//type的类型如下

TYPE_CUSTOM = 0;
TYPE_HOME = 1;
TYPE_WORK = 2;
TYPE_OTHER = 3;

 

 好的下面开始介绍VCard的导出和导入.

VCard规范 通俗点讲,就是让知道规范的人都能认识它.

在使用VCard时,我们需要下载VCard 的jar包

下载后里面会有2个Example {ReadExample.java / WriteExample.java} 。
但是凭借这两个Example,不足以让你更好的完成其他信息的备份和恢复,于是你要看下源码。

其中比较的2个类的源码如下.

View Code
View Code

最后附上导入导出的方法

复制代码
  1 package com.hh.assistant.app.vo;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.FileInputStream;
  5 import java.io.FileNotFoundException;
  6 import java.io.FileOutputStream;
  7 import java.io.IOException;
  8 import java.io.InputStreamReader;
  9 import java.io.OutputStreamWriter;
 10 import java.io.UnsupportedEncodingException;
 11 import java.util.ArrayList;
 12 import java.util.List;
 13 
 14 import a_vcard.android.provider.Contacts;
 15 import a_vcard.android.syncml.pim.VDataBuilder;
 16 import a_vcard.android.syncml.pim.VNode;
 17 import a_vcard.android.syncml.pim.vcard.ContactStruct;
 18 import a_vcard.android.syncml.pim.vcard.ContactStruct.ContactMethod;
 19 import a_vcard.android.syncml.pim.vcard.ContactStruct.PhoneData;
 20 import a_vcard.android.syncml.pim.vcard.VCardComposer;
 21 import a_vcard.android.syncml.pim.vcard.VCardException;
 22 import a_vcard.android.syncml.pim.vcard.VCardParser;
 23 import android.app.Activity;
 24 import android.content.ContentUris;
 25 import android.content.ContentValues;
 26 import android.database.Cursor;
 27 import android.net.Uri;
 28 import android.os.Environment;
 29 import android.provider.ContactsContract;
 30 import android.provider.ContactsContract.CommonDataKinds.Email;
 31 import android.provider.ContactsContract.CommonDataKinds.Phone;
 32 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 33 import android.provider.ContactsContract.RawContacts;
 34 import android.provider.ContactsContract.RawContacts.Data;
 35 import android.widget.Toast;
 36 
 37 
 38 /**
 39  * 联系人信息包装类
 40  * 
 41  * @author LW
 42  * 
 43  */
 44 public class ContactInfo {
 45 
 46     /** MUST exist */
 47     private String name; // 姓名
 48     
 49     /** 联系人电话信息 */
 50     public static class PhoneInfo{
 51         /** 联系电话类型 */
 52         public int type;
 53         /** 联系电话 */
 54         public String number;
 55     }
 56     
 57     /** 联系人邮箱信息 */
 58     public static class EmailInfo{
 59         /** 邮箱类型 */
 60         public int type;
 61         /** 邮箱 */
 62         public String email;
 63     }
 64     
 65     private List<PhoneInfo> phoneList = new ArrayList<PhoneInfo>(); // 联系号码
 66     private List<EmailInfo> email = new ArrayList<EmailInfo>(); // Email
 67 
 68     /**
 69      * 构造联系人信息
 70      * @param name 联系人姓名 
 71      */
 72     public ContactInfo(String name) {
 73         this.name = name;
 74     }
 75     
 76     /** 姓名 */
 77     public String getName() {
 78         return name;
 79     }
 80     /** 姓名 */
 81     public ContactInfo setName(String name) {
 82         this.name = name;
 83         return this;
 84     }
 85     /** 联系电话信息 */
 86     public List<PhoneInfo> getPhoneList() {
 87         return phoneList;
 88     }
 89     /** 联系电话信息 */
 90     public ContactInfo setPhoneList(List<PhoneInfo> phoneList) {
 91         this.phoneList = phoneList;
 92         return this;
 93     }
 94     /** 邮箱信息 */
 95     public List<EmailInfo> getEmail() {
 96         return email;
 97     }
 98     /** 邮箱信息 */
 99     public ContactInfo setEmail(List<EmailInfo> email) {
100         this.email = email;
101         return this;
102     }
103 
104     @Override
105     public String toString() {
106         return "{name: "+name+", number: "+phoneList+", email: "+email+"}";
107     }
108     
109     /**
110      * 联系人
111      *         备份/还原操作
112      * @author LW
113      *
114      */
115     public static class ContactHandler {
116 
117         private static ContactHandler instance_ = new ContactHandler();
118         
119         /** 获取实例 */
120         public static ContactHandler getInstance(){
121             return instance_;
122         }
123         
124         /**
125          * 获取联系人指定信息
126          * @param projection 指定要获取的列数组, 获取全部列则设置为null
127          * @return
128          * @throws Exception
129          */
130         public Cursor queryContact(Activity context, String[] projection){
131             // 获取联系人的所需信息
132             Cursor cur = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, projection, null, null, null);
133             return cur;
134         }
135         
136         /**
137          * 获取联系人信息
138          * @param context
139          * @return
140          */
141         public List<ContactInfo> getContactInfo(Activity context){
142             List<ContactInfo> infoList = new ArrayList<ContactInfo>();
143             
144             Cursor cur = queryContact(context, null);
145             
146             if(cur.moveToFirst()){
147                 do{
148                     
149                     // 获取联系人id号
150                     String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
151                     // 获取联系人姓名
152                     String displayName = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
153                     ContactInfo info = new ContactInfo(displayName);// 初始化联系人信息
154                     
155                     // 查看联系人有多少电话号码, 如果没有返回0
156                     int phoneCount = cur.getInt(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
157                     
158                     if(phoneCount>0){
159                         
160                         Cursor phonesCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + id , null, null);
161                         
162                         if(phonesCursor.moveToFirst()) {
163                             List<ContactInfo.PhoneInfo> phoneNumberList = new ArrayList<ContactInfo.PhoneInfo>();
164                             do{
165                                 // 遍历所有电话号码
166                                 String phoneNumber = phonesCursor.getString(phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
167                                 // 对应的联系人类型
168                                 int type = phonesCursor.getInt(phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
169                                 
170                                 // 初始化联系人电话信息
171                                 ContactInfo.PhoneInfo phoneInfo = new ContactInfo.PhoneInfo();
172                                 phoneInfo.type=type;
173                                 phoneInfo.number=phoneNumber;
174                                 
175                                 phoneNumberList.add(phoneInfo);
176                             }while(phonesCursor.moveToNext());
177                             // 设置联系人电话信息
178                             info.setPhoneList(phoneNumberList);
179                         }
180                     }
181                     
182                     // 获得联系人的EMAIL
183                     Cursor emailCur = context.getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID+"="+id, null, null);
184                     
185                     if(emailCur.moveToFirst()){
186                         List<ContactInfo.EmailInfo> emailList = new ArrayList<ContactInfo.EmailInfo>();
187                         do{
188                             // 遍历所有的email
189                             String email = emailCur.getString(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA1));
190                             int type = emailCur.getInt(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
191                             
192                             // 初始化联系人邮箱信息
193                             ContactInfo.EmailInfo emailInfo=new ContactInfo.EmailInfo();
194                             emailInfo.type=type;    // 设置邮箱类型
195                             emailInfo.email=email;    // 设置邮箱地址
196                             
197                             emailList.add(emailInfo);
198                         }while(emailCur.moveToNext());
199                         
200                         info.setEmail(emailList);
201                     }
202                     
203                     //Cursor postalCursor = getContentResolver().query(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI, null, ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + "=" + id, null, null);
204                     infoList.add(info);
205                 }while(cur.moveToNext());
206             }
207             return infoList;
208         }
209         
210         /**
211          * 备份联系人
212          */
213         public void backupContacts(Activity context, List<ContactInfo> infos){
214             
215             try {
216                 
217                 String path = Environment.getExternalStorageDirectory() + "/contacts.vcf";
218                 
219                 OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(path),"UTF-8");
220                 
221                 VCardComposer composer = new VCardComposer();
222                 
223                 for (ContactInfo info : infos)
224                 {
225                     ContactStruct contact = new ContactStruct();
226                     contact.name = info.getName();
227                     // 获取联系人电话信息, 添加至 ContactStruct 
228                     List<ContactInfo.PhoneInfo> numberList = info
229                             .getPhoneList();
230                     for (ContactInfo.PhoneInfo phoneInfo : numberList)
231                     {
232                         contact.addPhone(phoneInfo.type, phoneInfo.number,
233                                 null, true);
234                     }
235                     // 获取联系人Email信息, 添加至 ContactStruct 
236                     List<ContactInfo.EmailInfo> emailList = info.getEmail();
237                     for (ContactInfo.EmailInfo emailInfo : emailList)
238                     {
239                         contact.addContactmethod(Contacts.KIND_EMAIL,
240                                 emailInfo.type, emailInfo.email, null, true);
241                     }
242                     String vcardString = composer.createVCard(contact,
243                             VCardComposer.VERSION_VCARD30_INT);
244                     writer.write(vcardString);
245                     writer.write("\n");
246                     
247                     writer.flush();
248                 }
249                 writer.close();
250             
251             } catch (UnsupportedEncodingException e) {
252                 e.printStackTrace();
253             } catch (FileNotFoundException e) {
254                 e.printStackTrace();
255             } catch (VCardException e) {
256                 e.printStackTrace();
257             } catch (IOException e) {
258                 e.printStackTrace();
259             }
260             
261             Toast.makeText(context, "备份成功!", Toast.LENGTH_SHORT).show();
262         }
263         
264         
265         /**
266          * 获取vCard文件中的联系人信息 
267          * @return 
268          */
269         public List<ContactInfo> restoreContacts() throws Exception {
270             List<ContactInfo> contactInfoList = new ArrayList<ContactInfo>();
271             
272             VCardParser parse = new VCardParser();
273             VDataBuilder builder = new VDataBuilder();
274             String file = Environment.getExternalStorageDirectory() + "/contacts.vcf";
275             
276             BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
277             
278             String vcardString = "";
279             String line;
280             while((line = reader.readLine()) != null) {
281                 vcardString += line + "\n";
282             }
283             reader.close();
284             
285             boolean parsed = parse.parse(vcardString, "UTF-8", builder);
286             
287             if(!parsed){
288                 throw new VCardException("Could not parse vCard file: "+ file);
289             }
290             
291             List<VNode> pimContacts = builder.vNodeList;
292             
293             for (VNode contact : pimContacts) {
294                 
295                 ContactStruct contactStruct=ContactStruct.constructContactFromVNode(contact, 1);
296                 // 获取备份文件中的联系人电话信息
297                 List<PhoneData> phoneDataList = contactStruct.phoneList;
298                 List<ContactInfo.PhoneInfo> phoneInfoList = new ArrayList<ContactInfo.PhoneInfo>();
299                 for(PhoneData phoneData : phoneDataList){
300                     ContactInfo.PhoneInfo phoneInfo = new ContactInfo.PhoneInfo();
301                     phoneInfo.number=phoneData.data;
302                     phoneInfo.type=phoneData.type;
303                     phoneInfoList.add(phoneInfo);
304                 }
305                 
306                 // 获取备份文件中的联系人邮箱信息
307                 List<ContactMethod> emailList = contactStruct.contactmethodList;
308                 List<ContactInfo.EmailInfo> emailInfoList = new ArrayList<ContactInfo.EmailInfo>();
309                 // 存在 Email 信息
310                 if (null!=emailList)
311                 {
312                     for (ContactMethod contactMethod : emailList)
313                     {
314                         if (Contacts.KIND_EMAIL == contactMethod.kind)
315                         {
316                             ContactInfo.EmailInfo emailInfo = new ContactInfo.EmailInfo();
317                             emailInfo.email = contactMethod.data;
318                             emailInfo.type = contactMethod.type;
319                             emailInfoList.add(emailInfo);
320                         }
321                     }
322                 }
323                 ContactInfo info = new ContactInfo(contactStruct.name).setPhoneList(phoneInfoList).setEmail(emailInfoList);
324                 contactInfoList.add(info);
325             }
326             
327             return contactInfoList;
328         }
329 
330         
331         /**
332          * 向手机中录入联系人信息
333          * @param info 要录入的联系人信息
334          */
335         public void addContacts(Activity context, ContactInfo info){
336             ContentValues values = new ContentValues();
337             //首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获取系统返回的rawContactId
338             Uri rawContactUri = context.getContentResolver().insert(RawContacts.CONTENT_URI, values);
339             long rawContactId = ContentUris.parseId(rawContactUri);
340             
341             //往data表入姓名数据
342             values.clear();
343             values.put(Data.RAW_CONTACT_ID, rawContactId);
344             values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
345             values.put(StructuredName.GIVEN_NAME, info.getName());
346             context.getContentResolver().insert(
347                     android.provider.ContactsContract.Data.CONTENT_URI, values);
348             
349             // 获取联系人电话信息
350             List<ContactInfo.PhoneInfo> phoneList = info.getPhoneList();
351             /** 录入联系电话 */
352             for (ContactInfo.PhoneInfo phoneInfo : phoneList) {
353                 values.clear();
354                 values.put(android.provider.ContactsContract.Contacts.Data.RAW_CONTACT_ID, rawContactId);
355                 values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
356                 // 设置录入联系人电话信息
357                 values.put(Phone.NUMBER, phoneInfo.number);
358                 values.put(Phone.TYPE, phoneInfo.type);
359                 // 往data表入电话数据
360                 context.getContentResolver().insert(
361                         android.provider.ContactsContract.Data.CONTENT_URI, values);
362             }
363             
364             // 获取联系人邮箱信息
365             List<ContactInfo.EmailInfo> emailList = info.getEmail();
366             
367             /** 录入联系人邮箱信息 */
368             for (ContactInfo.EmailInfo email : emailList) {
369                 values.clear();
370                 values.put(android.provider.ContactsContract.Contacts.Data.RAW_CONTACT_ID, rawContactId);
371                 values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
372                 // 设置录入的邮箱信息
373                 values.put(Email.DATA, email.email);
374                 values.put(Email.TYPE, email.type);
375                 // 往data表入Email数据
376                 context.getContentResolver().insert(
377                         android.provider.ContactsContract.Data.CONTENT_URI, values);
378             }
379             
380         }
381         
382     }
383 }
复制代码
复制代码
 1 // 获取联系人处理实例
 2         ContactInfo.ContactHandler handler=ContactInfo.ContactHandler.getInstance();
 3         
 4         switch (id) {
 5         case R.id.save_linkman:
 6             // 获取要备份的信息
 7             List<ContactInfo> _infoList = handler.getContactInfo(this);
 8             handler.backupContacts(this, _infoList);    // 备份联系人信息
 9             break;
10 
11         case R.id.restore_linkman:    // 恢复
12             try {
13                 // 获取要恢复的联系人信息
14                 List<ContactInfo> infoList = handler.restoreContacts();
15                 for (ContactInfo contactInfo : infoList) {
16                     // 恢复联系人
17                     handler.addContacts(this, contactInfo);
18                 }
19                 
20                 Toast.makeText(this, "导入联系人信息成功!", Toast.LENGTH_LONG);
21                 
22             } catch (Exception e) {
23                 Toast.makeText(this, "导入联系人信息失败!", Toast.LENGTH_SHORT).show();
24                 e.printStackTrace();
25             }
26             
27             break;
28         }
复制代码

这篇关于VCard联系人备份恢复(导入/导出)详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/275070

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

LabVIEW FIFO详解

在LabVIEW的FPGA开发中,FIFO(先入先出队列)是常用的数据传输机制。通过配置FIFO的属性,工程师可以在FPGA和主机之间,或不同FPGA VIs之间进行高效的数据传输。根据具体需求,FIFO有多种类型与实现方式,包括目标范围内FIFO(Target-Scoped)、DMA FIFO以及点对点流(Peer-to-Peer)。 FIFO类型 **目标范围FIFO(Target-Sc

019、JOptionPane类的常用静态方法详解

目录 JOptionPane类的常用静态方法详解 1. showInputDialog()方法 1.1基本用法 1.2带有默认值的输入框 1.3带有选项的输入对话框 1.4自定义图标的输入对话框 2. showConfirmDialog()方法 2.1基本用法 2.2自定义按钮和图标 2.3带有自定义组件的确认对话框 3. showMessageDialog()方法 3.1