Android网络地址簿同步的方式
网络地址本为用户提供三种数据同步方式:
1.地址本备份(上传):用户通过点击手机终端上的“备份”菜单实现手机终端数据全量备份到服务器上,并且服务器上原来的所有地址本数据将被自动删除到回收站中,使得终端与服务器上的地址本数据保持一致;采用OMA SyncML DS 协议定义的“客户端刷新同步(Refresh Sync from Client Only)”方式实现。
2.地址本恢复(下载):用户通过点击手机终端上的“恢复”菜单实现手机终端数据全量备份到服务器上,并且服务器会对数据进行比对分析将服务器原来有而手机终端没有的地址本数据恢复到手机终端上,使得终端与服务器上的地址本数据保持一致;采用OMA SyncML DS 协议定义的“慢同步(Slow Sync)”方式实现。
3.地址本自动更新:用户对手机终端上的地址本数据进行增加、删除、修改操作后,手机终端自动将这些增、删、改地址本数据信息同步到服务器,服务器对这些数据进行分析后将更新服务器上相应地址本数据,并且把服务器上自上次与终端同步(包括地址本备份、恢复、自动更新)后增加、删除、修改的数据同步到手机上,使得终端与服务器上的地址本数据保持一致;采用OMA SyncML DS 协议定义的“双向同步(Two-Way Sync)”方式实现。
http://docs.oracle.com/cd/E19957-01/820-3751/ggyas/index.html
问题一:双向同步与慢同步的区别?
a.双向同步-客户端与服务器互相传递表中的更改内容,进行增量更改
b.慢同步-双向同步的一种方式,客户端和服务器都传输整个表的内容(包括更改的和未更改的记录),并将收到的所有数据进行逐项比较,并对本地数据库进行增量更改。由于这种同步方式传输的数据量大,因此效率低下。
问题二:如何上传联系人头像?
系统中主要从相机,媒体库和图片库中获取图像,其中从相机和媒体库取图片的路径保存在本地Contact表中,而从图片库中获取的是图片对象的ID(数字),即图片库中的图片全部在resource包下。
上传图片只能上传图片的二进制数据,服务器提供的接口 :
FillContactElement(long dwSessId, long dwContactId, int iItem, byte[] sValue)
dwSessId:输入参数,会话ID,本次同步的唯一ID标识
dwContactId:输入参数,联系人ID,本次会话中该联系人的唯一ID标识
iItem:输入参数,联系人项目,表示联系人信息中的项目
sValue:输入参数,联系人项目的值
1)如何获取相机,媒体库和图片库的图片并转为上传的二进制?
a.获取图片的BitmapDrawable
1 public static Drawable getImage(String path)
2 {
3 Drawable d = null;
4 Logger.v("UIUtity getImage(String path) Access");
5 if (path == null || path.length() == 0)
6 {
7 return null;
8 }
9 else if (ValidateUtil.validateType(path, ValidateUtil.REGEX_NUMBER))
10 {
11 d = ConfigurationManager.getInstance()
12 .getContext()
13 .getResources()
14 .getDrawable(Integer.valueOf(path));
15
16 }
17 else
18 {
19 d = BitmapDrawable.createFromPath(path);
20 }
21 drawableIconMap.put(d, path);
22 return d;
23 }
b.把drawable转为bytes
1 public static byte[] drawable2Bytes(BitmapDrawable d)
2 {
3 ByteArrayOutputStream bos = new ByteArrayOutputStream();
4 Bitmap bmp = d.getBitmap();
5 bmp.compress(Bitmap.CompressFormat.JPEG, 100, bos);
6 return bos.toByteArray();
7 }
2.如何把从服务器得到的二进制转为图片,并保存到本地?
a.把二进制转为图片
1 public static Drawable bytes2Drawable(byte[] bytes)
2 {
3 Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, null);
4 BitmapDrawable bitmapDrawable = new BitmapDrawable(bmp);
5 return bitmapDrawable;
6 }
b.把图片保存到本地,图片内容
1 public static String saveBitMap(String name, Bitmap bitmap)
2 {
3 ProfileInfo fileInfo = ClientManager.getInstance()
4 .getProfileManager()
5 .getCurrentProfile();
6 FileOutputStream fos = null;
7 File f = null;
8 try
9 {
10 f = fileInfo.retrieveResource(ResourceType.JPEG, name + ".JPEG");
11 fos = new FileOutputStream(f);
12 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
13 fos.flush();
14 fos.close();
15 }
16 catch (FileNotFoundException e)
17 {
18 Logger.e(e);
19 }
20 catch (IOException e)
21 {
22 Logger.e(e);
23 }
24 catch (Exception e)
25 {
26 Logger.e(e);
27 }
28 if (f != null && !TextUtils.isEmpty(f.getAbsolutePath()))
29 return f.getAbsolutePath();
30 else
31 return "";
32 }
由于图片保存到本地数据库是路径,所以要把图片的路径和图片对应的Drawable放在一个Map中。
问题三出现'Application No Responding'
解决办法:
利用队列解决
1 private class SyncTaskHandler
2 {
3 private ArrayList<SyncTask> list = new ArrayList<SyncTask>();
4
5 private SyncStatus curStatus;
6
7 private boolean isFirst = true;
8
9 private SyncTaskHandler()
10 {
11 curStatus = SyncStatus.IDLE;
12 }
13
14 public void submit(SyncTask task)
15 {
16 if (!list.contains(task))
17 {
18 list.add(task);
19 }
20 if (curStatus == SyncStatus.IDLE)
21 {
22 executeTask();
23 curStatus = SyncStatus.PROCESSING;
24 }
25 }
26
27 public boolean isFirst()
28 {
29 return isFirst;
30 }
31
32 public void idle()
33 {
34 if (isFirst)
35 {
36 isFirst = false;
37 }
38 if (list.size() > 0)
39 {
40 executeTask();
41 }
42 else
43 {
44 this.curStatus = SyncStatus.IDLE;
45 }
46 }
47
48 private void executeTask()
49 {
50 final SyncTask task = list.remove(0);
51 ThreadUtils.execute(new Runnable()
52 {
53 @Override
54 public void run()
55 {
56 startNBAService(task.value());
57 }
58 });
59 }
60 }
1 public static enum SyncStatus
2 {
3 PROCESSING, IDLE
4 }
2011-12-22