武汉理工大学华夏学院
课 程 报 告
课程名称:智能手机软件开发
题 目: 基于Android的手机通讯录的设计与实现
专 业 信息工程系 班 级 学 号 姓 名
成 绩 指导教师
2015年3月23日至2015年6月12日
智能手机软件开发大作业
根据所学的Android 手机开发的知识,采用Eclipse、JAVA开发一个基于Android平台的手机通讯录软件,具体要求如下: 1.要发该软件能够在Android4。0 以上的平台上运行。 2。要求软件界面美观,操作方便,符合日常使用规范。
3。能够通过该手机通讯录来添加新的联系人,用来存放联系人的姓名、单位、电话、QQ、地址等信息。
4.能够通过该手机通讯录来编辑联系人信息,来修改联系人的个人信息。 5。能够通过该手机通讯录来调用系统的通信接口,直接给用户发短信,打电话.
--
--
6。在手机通讯录中,添加合适的菜单,来操作手机通讯录. 7。将开发的过程写成报告,要求内容完整,格式规范,条理清晰。
1 设计目的
随着手机通讯录功能的不断加强与完善,手机通讯录对于人们的意义,已
不仅仅像记事簿一样显示通讯地址,而是向着个性化、人性化的方向发展移动终端的应用软件和需要的服务将会有很大的发展空间.根据这个特点,设计一个基于Android平台的通讯录系统,能根据手机的特点,存储,管理,修改联系人信息,并且能够根据选定的联系人,对其拨打电话,发送短信等。
手机通讯录作为手机的基本功能之一,每天我们都在频繁地使用着.根据手机功能使用调查显示,通讯录从无到有,从英文到中文,经过了十几年的发展历程,今后的发展趋势就是从通讯录发展为名片夹,也就是在一个人名下,可以存储座机、手机、单位、地址、电子邮件等内容.所以手机通讯录功能越来越齐全,满足了人们的需求。
2 开发环境
由于该android通讯录是一个基于Java语言开发软件,所以选择了Eclipse3.4作为开发平台,作为插件,它能够安装Android SDK,从而可以安装使用Android虚拟机,使得程序得以开发,亦更为方便。
本通讯录系统就是在Eclipse3.4+Android平台环境下编写设计而成的.
3 需求分析
该系统针对的主要用户是Android手机用户。Android手机通信管理系统包括以下主要内容:
(1) 用户通过联系人功能可以保存联系人的详细信息,可以对联系人进行编辑、删除、拨打电话、发送短信可以根据索引条件搜索联系人。
(2) 用户通过短信记录功能可以发送短信,删除短信记录.
--
--
(3) 用户通过SD卡所储存信息向通讯录批量导入联系人信息. (4) 用户通过个人中心可以设置自己的详细信息,这样方便其他人了解自己,也可以将具有相同名字的联系人合并.
要设计一个良好的手机通讯录,就必须首先明确该应用环境对系统的要求。Android手机通讯录应用背景:方便用户快捷通讯。
(1)类似于传统手机通讯录的联系人的添加、修改、查找、删除功能。 (2)指定联系人后,录音并发送给该联系人的留言功能。 (3)通过通讯录访问联系人的微博以实现与联系人互动的功能。 (4)接收短信、电话、语音留言和微博留言的信息并提醒用户。 (5)保存用户自身的个人信息以用于与他人联系时显示身份。
4 概要设计
ﻩ下面数据流图是对于Android手机通讯管理软件主要功能模块包括的简单结构图:联系人查看、联系人编辑、联系人添加、联系人删除、呼叫、发送短信、搜索,如图所示:
添 查 编 删 发送搜 呼 加 看 4.1辑 Andro除 d手机通讯管理软件主要功能模块短信 索 叫 图 i
通讯列表 Android手机通讯 联系人列表界面主菜单中包括添加联系人、搜索联系人、关于及查看系统版本号、退出菜单项.点击添加联系人,则进入联系人添加界面,添加成功后返回列表界面.点击搜索菜单,则进入联系人搜索界面,输入联系人的全名或一个字,即可查找相关联系人,点击联系人会进入联系人查看界面,可以对联系人进行编辑、删除、拨打电话、发送短信.如下图所示的Android手机通讯管理软件业务流程图.
--
--
开始 选则功能 选中条目 新建 编辑 删除 拨打电话 发送短信 输入新建联系人信搜索 输入搜索条件 更新数据库 显示搜索结果 结束 图4。2 Android手机通讯管理软件业务流程图
5 数据库设计
5。1 SQLite数据库简介
SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了.它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快.SQLite第一个Alpha版本诞生于2000年5月。 至今已经有10个年头,SQLite也迎
--
--
来了一个版本 SQLite 3已经发布。
本系统采用的是Android系统自带的SQLite轻型数据库数据库.因此占用资源非常小。 5。2 数据库表结构
首先创建数据库,在数据库中创建表用来存储联系人数据,其中包括联系人姓名、手机号、QQ、地址等联系方式。
6 详细设计与实现
6.1联系人浏览模块
6.1。1进入首界面,显示联系人列表。点击某个联系人会进入查看联系人界面,可以查看联系人的详细信息,对联系人进行编辑、删除、拨打电话发送短信等。截图所示:
--
--
图 6.1.1 通讯录联系人列表模块界面
6.1.2点击菜单按钮时,就会显示添加、查找、关于和退出功能。如果点击退出菜单,则会退出该软件。如图所示:
图6.1。2 通讯录主菜单项模块
6。1。3长按菜单显示Android手机通讯截图如图所示:
--
--
图6.1.3 通讯录联系人界面菜单模块
6.2查看联系人模块
6。2.1在联系人界面点中击某个联系人,则会跳转到该界面.该软件实现了给联系人拨打电话和发送短信的功能。查看联系人界面截图如图所示:
图6.2 手机通讯查看联系人模块界面
6.3编辑联系人模块
6.3.1联系人编辑界面设置了返回列表菜单和删除联系人菜单。点击返回列表
--
--
菜单,会返回到联系人浏览界面。编辑联系人界面如图所示:
图6.3 手机通讯录编辑联系人界面模块
6.4查找联系人模块
查找到所有包含该部分的联系人,并在ListView中显示出来所有的联系人的姓名和手机号码,截图如图所示:
图6。4 通讯录查找联系人模块界面
--
--
7 总结
这学期的智能手机开发课程的学习,让我了解到手机开发端应用的广泛性,以
及对自己所学知识的总结,做手机通讯录,让我了解到手机已经成为日常生活中不可分割的一部分,所以手机上的功能满足人们的需求,才是手机通讯录开的重要性。
对于这次的课程设计,使我发现了自己所掌握的知识是真正如此的缺乏,自己综合应用所学的专业知识能力是如此的不足通过这次开发项目,我们学会了如何在一个项目中集成多种技术,如何合理的耦合各种小功能,如何解决各种开发中出现的问题。同时在这次开发中出现的问题也暴露出了我们对java程序设计的一些问题,以及自己的动手能力还需要提高,而且做一个项目首先要明白这个项目的中心思想,这样才有目的去设计。
通过课程设计,使我深深体会到,干任何事都必须耐心,细致,课程设计过程中,许多迷惑有时不免令我感到有些心烦意乱,有几次因为不小心而出错,只能毫不情意地重来。但一想起老师对我们耐心的教导,认真对待的良好习惯.这次课程设计使我在工作作风上得到了一次难得的磨练,一个人的性格很大程度上决定一件事情的进展以及对工作的态度和生活的态度,所以养成好的习惯能够帮助我克服各种苦难,能够帮助我在今后的学习中脚踏实地的工作。
通过这次手机开发通讯录课程设计,我能够更加深刻的了解到手机通讯录开发的前景以及所需的知识,总之在今后的学习中自己应该了解如今社会上开发手机通讯录所需的最新的技术,不能一成不变,只看书本上的知识,养成自我学习的良好习惯。
8 参考文献
[1] 罗伟. 基于 Android平台的即时通讯系统的研究与实现[D].湖南师范大学, 2009 .
[2] 李刚,《疯狂Java讲义》,电子工业出版社,2008 [3] 程峰,《JAVA核心技术》,机械工业出版社,2007
--
--
[4] 王鹏,《JAVA语言程序设计》,大连理工出版社,2005
9 附录源代码
public class DBHelper {
/*
*操作数据库和各个表 */
public static final String DATABASE_NAME="CONTACT_DB”; public static final String TABLE_CONTACTER=”contact_person”;
public static final String TABLE_MOBLIEPHONE=”phone_number\"; public static final String TABLE_GROUP="mygroup”; public static final String TABLE_EMAIL="email”; public static final String TABLE_QQ="qq\";
public static final String TABLE_HOMEPHONE="home_phone_number”; public static final String TABLE_ADDRESS=”address\"; public static final String TABLE_FAX="fax”; //创建表的SQL语句
public static String[] CreateTabelSQL;
private static SQLiteDatabase dbInstance; public static final int VERSION = 4; private MyDBHelper myDBHelper; private Context context;
public DBHelper(Context context,String[] createtablesql) { this.context=context; this.CreateTabelSQL=createtablesql; }
public DBHelper(Context context) {
ﻩ this.context=context; } /**
* 打开数据库 */
public void openDatabase() { if(dbInstance==null) { //创建数据库
--
--
ﻩ myDBHelper= new MyDBHelper(context, DATABASE_NAME, VERSION);
ﻩﻩ dbInstance=myDBHelper.getWritableDatabase(); } } /**
ﻩ* 返回所有联系人 */
public ArrayList〈HashMap<String, Object>〉 getAllContacter(String condition) { ArrayList<HashMap〈String, Object>> contaclist = new ArrayList(); Cursor cursor;
ﻩ if(condition==null||condition.trim()。equals(\"\")) cursor=dbInstance。query(TABLE_CONTACTER, ﻩ new String[]{"id\"name\","headImage\l, null, null, null, null); ﻩ else { ﻩ StringBuffer sqlBuffer=new StringBuffer(); ﻩ sqlBuffer。append(\"select id,name,headImage from \") ﻩﻩ 。append(TABLE_CONTACTER) ﻩ .append(\" where name like '%") ﻩﻩ .append(condition) ﻩ .append(”%'\"); cursor=dbInstance。rawQuery(sqlBuffer.toString(), null); ﻩ } cursor.moveToFirst(); while(!cursor.isAfterLast()) {
ﻩ HashMap〈String, Object〉 item=new HashMap<String, Object>();
ﻩﻩ item.put(”contacter_id\", cursor.getInt(cursor.getColumnIndex(”id”)));
ﻩ item.put("name", cursor.getString(cursor.getColumnIndex(”name”))); item.put(”headimage", cursor。getString(cursor.getColumnIndex(\"headImage\")));
ﻩﻩ //返回第一个手机电话号码
ﻩ Cursor phoneCursor=dbInstance。query(TABLE_MOBLIEPHONE,
ﻩﻩ ﻩ new String[]{\"phone_number\=?\", ﻩ ﻩ new String[]{String.valueOf(cursor。getInt(cursor.getColumnIndex(”id")))},
ﻩﻩ ﻩ null, null, null);
--
--
ﻩﻩ phoneCursor。moveToFirst(); item.put(\"phonenumber", phoneCursor.getString(phoneCursor。getColumnIndex(”phone_number"))); contaclist.add(item); ﻩ cursor。moveToNext(); ﻩ }
ﻩ return contaclist; } /**
* 根据编号返回一个联系人 */
public Contacter getContacter(int id) {
ﻩ Contacter contacter = new Contacter(); Cursor contacterCursor =dbInstance.query(TABLE_CONTACTER, ﻩ new String[]{"id”,”group_name”,”name\",\"nick_name”,”birthday\orkingunits”,\"headImage"}, ﻩ "id=?\",
ﻩ ﻩ new String[]{String。valueOf(id)}, null, null, null); ﻩ contacter。id=id; contacterCursor。moveToFirst();
ﻩ contacter.name=contacterCursor.getString(contacterCursor。getColumnIndex("name"));
ﻩ contacter。nickname=contacterCursor.getString(contacterCursor.getColumnIndex(”nick_name”)); contacter。workingunits=contacterCursor.getString(contacterCursor.getColumnIndex("workingunits”));
ﻩ if(contacterCursor.getString(contacterCursor.getColumnIndex("birthday\")).trim()!=null
ﻩ ﻩ &&!contacterCursor.getString(contacterCursor.getColumnIndex(\"birthday”))。trim().equals(\"”)) { String string=contacterCursor.getString(contacterCursor.getColumnIndex("birthday\")).trim();
ﻩ contacter.birthday=Date.valueOf(contacterCursor。getString(contacterCursor.getColumnIndex("birthday\"))); ﻩ } contacter.headimage=contacterCursor.getInt(contacterCursor.getColumnIndex(”headImage”)); //联系人的手机号码
ﻩ Cursor phoneCursor =dbInstance。query(TABLE_MOBLIEPHONE, ﻩ ﻩ new String[]{\"phone_number”}, ﻩﻩ \"id=?\",
--
--
new String[]{String.valueOf(id)}, null, null, null); ﻩ phoneCursor。moveToFirst(); contacter.mobilephone=new String[phoneCursor。getCount()]; for(int i=0;i〈phoneCursor。getCount();i++) { contacter.mobilephone[i]=phoneCursor。getString(phoneCursor.getColumnIndex(”phone_number”)); ﻩ phoneCursor.moveToNext(); ﻩ } //联系人的座机号码 Cursor homephoneCursor=dbInstance.query(TABLE_HOMEPHONE, new String[]{”home_number\, ﻩﻩ ”id=?”, ﻩﻩ new String[]{String.valueOf(id)}, null, null, null); homephoneCursor.moveToFirst();
ﻩ contacter.homephonenumber=new String[homephoneCursor.getCount()]; for(int i=0;i ﻩ //联系人的email ﻩ Cursor emailCursor=dbInstance。query(TABLE_EMAIL, ﻩ new String[]{”email\"}, ﻩﻩﻩ ”id=?\", new String[]{String。valueOf(id)}, null, null,null); ﻩ emailCursor.moveToFirst(); contacter.email=new String[emailCursor.getCount()]; ﻩ for(int i=0;i -- -- \"id=?", new String[]{String。valueOf(id)}, null, null,null); ﻩ contacter.faxnumber=new String[emailCursor。getCount()]; ﻩ faxCursor.moveToFirst(); ﻩ for(int i=0;i ﻩ faxCursor。moveToNext(); } ﻩ //联系人的地址 Cursor addressCursor=dbInstance.query(TABLE_ADDRESS, ﻩ ﻩ new String[]{\"add_code”,”province”,”city”,"street\",\"zip_code”,”country”}, ﻩ "id=?\", ﻩ new String[]{String。valueOf(id)}, null, null, null); ﻩ addressCursor。moveToFirst(); contacter。addresses=new address[addressCursor.getCount()]; for(int i=0;i〈addressCursor.getCount();i++) { contacter.addresses[i]=new address(); contacter.addresses[i].add_code=addressCursor。getIn(taddressCursor。getColumnIndex("add_code")); contacter。addresses[i].province=addressCursor。getString(addressCursor。getColumnIndex(”province\")); ﻩ contacter.addresses[i]。city=addressCursor.getString(addressCursor.getColumnIndex(\"city”)); contacter。addresses[i]。street=addressCursor.getString(addressCursor.getColumnIndex(”street\")); contacter.addresses[i].zip_code=addressCursor.getString(addressCursor.getColumnIndex(\"zip_code”)); ﻩ contacter。addresses[i]。coutry=addressCursor.getString(addressCursor.getColumnIndex(”country\")); ﻩ addressCursor.moveToNext(); } return contacter; } /* * 自动生成联系人编码 */ public int generateContacterID() { Cursor cursor=dbInstance.query(TABLE_CONTACTER, -- -- ﻩ new String[]{"id”}, null, null, null, null, null); cursor.moveToFirst(); int i=0; if(cursor.getCount()==0) ﻩ return 0; while(!cursor.isAfterLast()) { if(i!=cursor.getInt(cursor.getColumnIndex(”id"))) ﻩﻩﻩ return i; ﻩﻩ i++; ﻩﻩ cursor。moveToNext(); } ﻩ return i; } /** * 插入新的联系人 */ public boolean insertContacter(Contacter contacter) { boolean flag; int id=generateContacterID(); ﻩ //插入基本信息 flag=insertContactPerson(id,contacter。groupname, contacter。name, contacter.nickname, contacter。birthday, ﻩﻩ contacter。workingunits, contacter.headimage); //插入email ﻩ if(contacter。email!=null&&contacter。email.length〉0) ﻩ for(String email:contacter。email) ﻩ flag&=insertEmail(id, email); ﻩ //插入QQ if(contacter.email!=null&&contacter.QQ.length〉0) for(long qq:contacter.QQ) flag&=insertQQ(id, qq); ﻩ //插入传真 ﻩ if(contacter.faxnumber!=null&&contacter.faxnumber。length〉0) ﻩ for(String fax:contacter.faxnumber) flag&=insertFax(id, fax); //插入电话 if(contacter。mobilephone!=null&&contacter.mobilephone。length〉0) for(String phone:contacter.mobilephone) ﻩflag&=insertPhoneNumber(id, phone); ﻩ //插入座机号码 -- -- if(contacter.homephonenumber!=null&&contacter。homephonenumber。length〉0) for(String homephone:contacter.homephonenumber) ﻩ flag&=insertHomePhone(id, homephone); //插入地址 ﻩ int i=0; ﻩ if(contacter。addresses!=null&&contacter.addresses.length>0) for(address add:contacter。addresses) ﻩ { ﻩﻩ flag&=insertAddress(id, i++,add.province, ﻩ ﻩ add。city, add.street, add.zip_code, add。coutry); ﻩ } return flag; } /** * 更新联系人 */ public void updateContacter(Contacter contacter) { //先删除记录 removeContacter(String.valueOf(contacter.id)); ﻩ //再重新插入 ﻩ insertContacter(contacter); } /* * 删除联系人 */ public void removeContacter(String id) { ﻩ dbInstance.delete(TABLE_EMAIL, \"id=?", new String[]{id}); dbInstance。delete(TABLE_FAX, "id=?”, new String[]{id}); ﻩ dbInstance.delete(TABLE_HOMEPHONE, ”id=?”, new String[]{id}); ﻩ dbInstance。delete(TABLE_MOBLIEPHONE, \"id=?\", new String[]{id}); dbInstance.delete(TABLE_QQ, ”id=?”, new String[]{id}); ﻩ dbInstance。delete(TABLE_CONTACTER, \"id=?”, new String[]{id}); } //数据库插入函数 public boolean insertValuesToTable(String tableName,ContentValues values) { ﻩ if( (long) dbInstance.insert(tableName, null, values)==-1) return false; else { -- -- ﻩ return true; } } /* * 往表中插入数据 */ //往group插入数据 public boolean insertGroup(String groupname) { ContentValues values=new ContentValues(); values.put(”group_name", groupname); if (insertValuesToTable(TABLE_GROUP,values) ) ﻩ return true; else return false; } //往ContactPerson表插入数据 public boolean insertContactPerson(int id, ﻩ String groupname, String name, ﻩ String nickname, ﻩ Date birthday, ﻩﻩ String workiingunits, ﻩﻩ int headImage ﻩﻩ ) { ﻩ ContentValues values=new ContentValues(); ﻩ values.put("id”, id); values.put(”group_name", groupname); ﻩ values.put("name”, name); values.put(\"nick_name”, nickname); ﻩ values.put("birthday", birthday.toString()); values.put(\"workingunits”, workiingunits); values。put(”headImage”, headImage); if (insertValuesToTable(\"contact_person\",values) ) ﻩﻩ return true; ﻩ else return false; } //往Email表插入数据 public boolean insertEmail(int id,String email) { ContentValues values=new ContentValues(); ﻩ values。put(”id", id); -- -- values。put(\"email\); if (insertValuesToTable(”Email",values) ) ﻩﻩ return true; ﻩ else return false; } //往address表插入数据 public boolean insertAddress(int id, ﻩ int add_code, ﻩﻩ String province, ﻩ String city, ﻩ String street, ﻩ String zip_code, String country) { ﻩ ContentValues values=new ContentValues(); values。put(\"id\", id); values.put(\"add_code”, add_code); values.put(”province”, province); ﻩ values.put(\"city\", city); values。put(\"street”, street); ﻩ values.put(\"zip_code", zip_code); values.put("country", country); ﻩ if (insertValuesToTable(\"address\",values) ) ﻩ return true; ﻩﻩ else return false; } //往QQ表插入数据 public boolean insertQQ(int id,long QQ_number) { ﻩ ContentValues values=new ContentValues(); values.put(\"id\", id); ﻩ values.put("QQ_number", QQ_number); ﻩ if (insertValuesToTable("QQ”,values) ) ﻩﻩ return true; else return false; } //往fax表插入数据 public boolean insertFax(int id,String fax_number) { ContentValues values=new ContentValues(); ﻩ values。put(”id”, id); -- -- ﻩ values。put("fax_number”, fax_number); ﻩ if (insertValuesToTable(\"fax",values)) ﻩ return true; ﻩ else ﻩ return false; } //往home_phone_number表插入数据 public boolean insertHomePhone(int id,String home_number) { ContentValues values=new ContentValues(); values。put(\"id\", id); ﻩ values.put(”home_number", home_number); ﻩ if (insertValuesToTable(\"home_phone_number”,values) ) ﻩﻩ return true; ﻩﻩ else return false; } //往phone_number表插入数据 public boolean insertPhoneNumber(int id,String phone_number) { ﻩ ContentValues values=new ContentValues(); ﻩ values.put("id", id); ﻩ values。put(\"phone_number”, phone_number); ﻩ if (insertValuesToTable(\"phone_number”,values) ) ﻩ return true; ﻩ else return false; } /** * 自建的SQLiteOpenHelper, */ class MyDBHelper extends SQLiteOpenHelper { public MyDBHelper(Context context, String name,int version) { ﻩﻩsuper(context, name, null,version); } /**创建数据库 * */ ﻩ@Override ﻩpublic void onCreate(SQLiteDatabase db) { -- -- ﻩﻩ//创建表 for(String sql:CreateTabelSQL) ﻩﻩ{ ﻩ db.execSQL(sql); ﻩ } ﻩ} /**更新数据库 * */ ﻩ@Override ﻩpublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { ﻩﻩString sql = ”drop table if exists ” + TABLE_CONTACTER; ﻩdb.execSQL(sql); onCreate(db); ﻩ} } } 指导老师评语 设计过程中现场提问(或答辩)记载: 1. 手机通讯录开发如何实现删除功能? 答 :删除列表中的项就是及时刷新列表,跟UI线程有关系,数据的更新通 知 一定要在UI线程上做,不然会出现各种错误,比如出现adapter数据源改变,但没有及时收到通知的情况。在执行遍历删除的时候,最好不要每删一个就直接通知,将需要删除的contact保存到一个List然后通过handler发生消息,然后再由handler来处理。 2. 手机通讯录开发如何实现全选功能? 答 :实现全选功能,就只是用另外一个数据结构来存储被选中的状态,通过刷新列表来更新列表的显示状态。 -- -- 指导教师评语: 成绩评定: 指导教师(签名): 2015 年6月15日 -- 因篇幅问题不能全部显示,请点此查看更多更全内容