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         }
复制代码
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值