您的位置:首页 > 其它

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

2013-03-19 16:16 615 查看
文章摘自:/content/4725738.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         }



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: