公司以前的一个座机产品,前段时间要求增加新更能,其实这个功能在山寨机上早已经很普遍了,android手机里面也有做的比较好的,我手上的参照机就有MOTO的XT800。

客户要求通讯录同步,并没有详细的需求,关于怎么同步,客户也表达的很模糊。其实很多时候是这样,客户也不清楚他们到底要一个什么样的产品。此时,作为程序员,就必须替客户理清需求,甚至想到客户不曾想到的需求:

1、插入SIM卡后,设备能自动把联系人导入到联系人列表中,并且能给用户提供标识,表示该联系人属于SIM卡

2、拔出或更换SIM卡后,上次导入的联系人不能在出现

3、用户新建联系人,可以选择新建到SIM卡或者话机

4、可以复制联系人,包括从SIM卡复制到话机,话机复制到SIM卡

5、可以同时删除多个联系人,包括删除SIM卡和话机上的联系人,但是给客户提示删除的是SIM卡还是话机上的。

 

分析过程:

第一条需求,当前代码中有个类SimContacts(extends ADNList)完成了从SIM卡到话机的复制功能,但也只是个DEMO,功能并不完善。

代码如下:

@Override
        public void run() {
            ContentValues map = new ContentValues();
            ContentResolver cr = getContentResolver();
            Object[] parsed = new Object[2];
            int index = 0;
            while (!mCanceled && mCursor.moveToPosition(index++)) {
                String name = mCursor.getString(0);
                String number = mCursor.getString(1);
                Uri personUrl = parseName(name, parsed);
                if (personUrl == null) {
                    map.clear();
                    map.put(Contacts.People.NAME, (String) parsed[0]);
                    personUrl = People.createPersonInMyContactsGroup(cr, map);
                    if (personUrl == null) {
                        Log.e(TAG, "Error inserting person " + map);
                        continue;
                    }
                }
                map.clear();
                map.put(Contacts.People.Phones.NUMBER, number);
                map.put(Contacts.People.Phones.TYPE, (Integer) parsed[1]);
                Uri numberUrl = cr.insert(
                        Uri.withAppendedPath(personUrl, Contacts.People.Phones.CONTENT_DIRECTORY),
                        map);
                mProgressDialog.incrementProgressBy(1);
                if (numberUrl == null) {
                    Log.e(TAG, "Error inserting phone " + map + " for person " +
                            personUrl + ", removing person");
                    continue;
                }
            }
            mProgressDialog.dismiss();
            finish();
        }

实际上ADNList extends Activity, SimContacts创建一个线程,由线程完成联系人的导入,但是有两点不符合我的要求, 1,需要一个界面,我并不希望用户到一个界面导入,而是开机启动一个Serivce自动导入,2、没有标识这个联系人是SIM卡的,也就是说这个联系人我只是暂存到数据库里面,下次开机还是要删除的,但是如何找回这个SIM联系人,需要向people表中添加一个字段“local”进行标识。

 

第二条需求,有了第一条的字段,很容易查出来联系人的位置是话机还是SIM卡(并不是说联系人在SIM里面,而表示这个联系人是由SIM导入,不是在话机中创建的),如果是SIM卡就删除。但是是不是每次都要删除一遍呢,肯定不是,因为SIM读取很慢的,开机的时候获取SIM卡的id就可以了,如果跟上次不一样或者为空,就删除此前导入的联系人,导入新的联系人。

 

第三条需求,跟导入时候一样,如果用户选择新建到SIM卡,需要设置"local"为LOCAL_SIM,此外,两个联系人编辑界面肯定不一样,因为SIM卡之接受名字、号码、号码类型三种元素,没有什么相片之类的元素。因此SIM卡联系人编辑界面要自己编写。

 

第四、五条需求,需要用户操作,四个界面,当然可以复用一个ListActivity,由用户选择删除还是复制操作,目标是SIM卡还是话机。查询的表当然是phones。结合"local"字段,很容易完成这个功能。

 

需求分析清楚了,实现起来还有很多要注意的地方

1、当前未插入SIM卡或者SIM卡未准备好,为了不给用户造成干扰,应不允许用户复制,同时不允许新建联系人到SIM卡

2、用户删除SIM卡联系人和从话机复制到SIM卡时,实际上操作的不仅是数据库里面的联系人,还要操作实际SIM卡。