移动通信课程设计
题 目 联系人管理
姓名学号
院 系 计算机与软件学院
专 业
指导教师
二O一二年六月五日
Android是Google推出的开源手机操作系统。它基于Linux平台,由操作系统、中间件、用户界面和应用软件组成,具有以下5个特点:
1、开放性。
2、应用程序无界限。
3、应用程序是在平等条件下创建的。
4、应用程序可以轻松的嵌入网络。
5、应用程序可以并行运行。
Android平台特性:
1、应用程序框架 支持组件的重用与替换。
2、Dalvik 虚拟机 专为移动设备优化。
3、集成的浏览器 基于开源的WebKit 引擎。
4、优化的图形库 包括定制的2D图形库,3D图形库基于OpenGL ES 1.0 (硬件加速可选)。
5、SQLite 用作结构化的数据存储。
6、多媒体支持 包括常见的音频、视频和静态图像格式 (如 MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF)。
7、GSM 电话技术 (依赖于硬件)。
8、蓝牙Bluetooth, EDGE, 3G, 和 WiFi (依赖于硬件)。
9、照相机,GPS,指南针,和加速度计(accelerometer) (依赖于硬件)。
10、丰富的开发环境 包括设备模拟器,调试工具,内存及性能分析图表,和Eclipse集成开发环境插件。
Android 架构:如图1-1
图1-1 android架构
Android的应用层是用Java语言编写的运行在虚拟机上的程序,我们课程设计中所用到开发语言就是Java。
这次课程设计我做的是一个手机联系人管理的小软件,它可以设置联系的详细资料,帮助你记住你朋友的号码,邮编,住址等。把QQ里面的头像图片加载了进来,可以根据你的喜爱设置你的朋友的可爱头像,并且可以把联系人备份到SD卡中,方便保存,以免在刷机等突发情况时丢失联系人信息,下次只要重新从SD卡中导入到手机中即可,非常方便实用。
这是个信息膨胀的时代,随着网络的发展,我们的朋友越来越多,所以朋友的信息就越来越多了,朋友的手机号码,固定电话号码,家庭住址,邮编等。手机是现在人们最随身带的电子产品之一,所以想到了在手机上做一款联系人管理软件,来帮助我们记录和管理联系人的资料,随时随地都可以看到,方便实用,成本也很低。
基于以上的想法,进行了一些简单的可行性分析,主要问题在于技术的实现问题。就我们现在所学,对于实现我们想要的软件功能完全是可能的,所以借助于各种参考文献和网络资料,开始了软件的开发。
手机联系人管理软件包括以下几个功能:增加新的联系人,查找已有的联系人,删除单个联系人,删除所有联系人,修改联系人信息,备份联系人,还原联系人,检查软件更新信息。如图2-1所示:
图2-1功能总体模块图
用户进入系统后首先看到的是联系人列表界面,如果没有联系人则显示无信息。按下Menw建,我们会看到添加,查找,删除,菜单,退出几个选项,我们可以进行联系人的添加,查找,删除等操作。双击联系人,我们可以进入查看联系人信息的界面,可以进行修改资料,删除等操作。当我们点击菜单选项时,我们会看到显示所有联系人,删除所有,备份,还原,更新等,进行各项操作。如图2-2所示:
图2-2系统整体流程图
添加联系人模块,在我们添加联系人时,会进行名字的判断,联系人列表中是否已经有该联系的名字和信息,如果有则会提醒出现错误,要求你返回联系人列表。所以该数据流图会有一个判定框的功能实现该检查功能。具体的数据流图如图2-3所示:
图2-3添加联系人数据流图
我们在联系人菜单,对联系人进行信息修改时,需要对我们输入的联系人信息进行判断,判断其是否合乎我们要求的格式等,所以进行了一个判定,修改信息错误时会报错,具体功能实现,如下图2-4所示:
图2-4修改信息流程图
删除联系人得原理和添加差不多,只是会提示是否确认删除,以免失误删除重要信息,数据流图2-5所示:
图2-5删除联系人数据流图
在菜单的选项中,实现数据的备份与还原时,数据是在手机和SD卡之间转换的,导入导出之前都进行确认询问,最终完成操作。具体数据流图如图2-6所示:
图2-6数据备份流图
进行了数据流图的分析之后,开始准备进行软件界面风格的整体和细节设计,主界面,联系人界面,各种操作的界面,都进行了设想与设计,以方便软件功能的实现,由于初次做,所以布局等可能有些不合理,界面比较粗糙。
我们打开软件,第一个看到的就是联系人列表,显示联系人得头像,姓名和手机号码信息,很简约的风格,如图5-1所示。按下Menw键,我们可以看到下面会显示出5个功能菜单,所实现的功能是分别是添加新的联系人,查找具体的联系人,删除单个联系人,打开菜单选项和退出软件,如图5-2所示。
图5-1联系人列表界面
图5-2Menw功能选项
此时按下菜单键,会出现菜单的选项,出现如图5-3的功能选项。
图5-3菜单的功能选项
关键代码:
public class Main extends Activity {
ListView lv;
ArrayList list;
SimpleAdapter adapter;
GridView bottomMenuGrid;
GridView mainMenuGrid;
View mainMenuView;
View loginView;
LinearLayout searchLinearout;
LinearLayout mainLinearLayout;
EditText et_search;
EditText et_enter_file_name;
AlertDialog mainMenuDialog;
AlertDialog confirmDialog;
AlertDialog progressDialog;
AlertDialog enterFileNameDialog;
AlertDialog loginDialog;
boolean privacy = false;
int markedNum;
ArrayList<Integer> deleteId;
String[] main_menu_itemName = { "显示所有", "删除所有", "备份数据", "还原数据", "更新", "后退"};
//主菜单图片
int[] main_menu_itemSource = {
R.drawable.showall,
R.drawable.menu_delete,
R.drawable.menu_backup,
R.drawable.menu_restore,
R.drawable.menu_fresh,
R.drawable.menu_return};
String[] bottom_menu_itemName = { "增加", "查找", "删除", "菜单","退出" };
String fileName;
int[] bottom_menu_itemSource = {
R.drawable.menu_new_user,
R.drawable.menu_search,
R.drawable.menu_delete,
R.drawable.controlbar_showtype_list,
R.drawable.menu_exit };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mainLinearLayout = (LinearLayout)findViewById(R.id.list_ll);
DBHelper helper = new DBHelper(this);
helper.openDatabase();
list = helper.getAllUser(privacy);
lv = (ListView)findViewById(R.id.lv_userlist); //创建ListView对象
if(list.size() == 0) {
Drawable nodata_bg = getResources().getDrawable(R.drawable.nodata_bg);
mainLinearLayout.setBackgroundDrawable(nodata_bg);
setTitle("没有查到任何数据");
}
adapter = new SimpleAdapter(this,
list,
R.layout.listitem,
new String[]{"imageid","name","mobilephone"},
new int[]{R.id.user_image,R.id.tv_name,R.id.tv_mobilephone});
lv.setAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
HashMap item = (HashMap)arg0.getItemAtPosition(arg2);
int _id = Integer.parseInt(String.valueOf(item.get("_id")));
Intent intent = new Intent(Main.this,UserDetail.class);
User user = new User();
user._id = Integer.parseInt(String.valueOf(item.get("_id")));
user.address = String.valueOf(item.get("address"));
user.company = String.valueOf(item.get("company"));
user.email = String.valueOf(item.get("email"));
user.familyPhone = String.valueOf(item.get("familyphone"));
user.mobilePhone = String.valueOf(item.get("mobilephone"));
user.officePhone = String.valueOf(item.get("officephone"));
user.otherContact = String.valueOf(item.get("othercontact"));
user.position = String.valueOf(item.get("position"));
user.remark = String.valueOf(item.get("remark"));
user.username = String.valueOf(item.get("name"));
user.zipCode = String.valueOf(item.get("zipcode"));
user.imageId = Integer.parseInt(String.valueOf(item.get("imageid")));
intent.putExtra("user", user);
if(searchLinearout != null && searchLinearout.getVisibility()==View.VISIBLE) {
searchLinearout.setVisibility(View.GONE);
}
startActivityForResult(intent, arg2);
}
});
lv.setCacheColorHint(Color.TRANSPARENT); //设置ListView的背景为透明
lv.setOnItemLongClickListener(new OnItemLongClickListener(){
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
if(deleteId == null) {
deleteId = new ArrayList<Integer>();
}
HashMap item = (HashMap)arg0.getItemAtPosition(arg2);
Integer _id = Integer.parseInt(String.valueOf(item.get("_id")));
RelativeLayout r = (RelativeLayout)arg1;
ImageView markedView = (ImageView)r.getChildAt(2);
if(markedView.getVisibility() == View.VISIBLE) {
markedView.setVisibility(View.GONE);
deleteId.remove(_id);
} else {
markedView.setVisibility(View.VISIBLE);
deleteId.add(_id);
}
return true;
}
});
Drawable bgDrawable = getResources().getDrawable(R.drawable.list_bg);
lv.setSelector(bgDrawable);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(deleteId != null) {
deleteId.clear();
}
if(resultCode == 3 || resultCode == 4) {
DBHelper helper = new DBHelper(this);
list = helper.getAllUser(privacy);
adapter =
new SimpleAdapter(
this,
list,
R.layout.listitem,
new String[]{"imageid","name","mobilephone"},
new int[]{R.id.user_image,R.id.tv_name,R.id.tv_mobilephone});
if(list.size() > 0){
mainLinearLayout.setBackgroundDrawable(null);
}
}
lv.setAdapter(adapter);
if(resultCode == 3) {
lv.setSelection(list.size());
} else {
lv.setSelection(requestCode);
}
菜单的功能选项是显示所有联系人,删除所有联系人,备份联系人,还原联系人,检查更新和返回。如图5-4所示为备份功能。
图5-4备份功能选项
关键代码:
private void loadMainMenuDialog() {
if(mainMenuDialog == null) {
LayoutInflater li = LayoutInflater.from(this);
mainMenuView = li.inflate(R.layout.main_menu_grid, null);
mainMenuDialog = new AlertDialog.Builder(this).setView(mainMenuView).create();
mainMenuGrid = (GridView)mainMenuView.findViewById(R.id.gridview);
SimpleAdapter menuAdapter = getMenuAdapter(main_menu_itemName, main_menu_itemSource);
mainMenuGrid.setAdapter(menuAdapter);
mainMenuGrid.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
switch(arg2){
case 0:{
DBHelper helper = new DBHelper(Main.this);
list = helper.getAllUser(privacy);
adapter = new SimpleAdapter(
Main.this,
list,
R.layout.listitem,
new String[]{"imageid","name","mobilephone"},
new int[]{R.id.user_image,R.id.tv_name,R.id.tv_mobilephone});
lv.setAdapter(adapter);//显示所有数据
mainMenuDialog.dismiss();
break;
}
case 1:{
AlertDialog.Builder builder = new AlertDialog.Builder(Main.this);
confirmDialog = builder.create();
builder.setTitle("是否删除所有!?");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DBHelper helper = new DBHelper(Main.this);
helper.deleteAll(0);
list = helper.getAllUser(privacy);
adapter = new SimpleAdapter(
Main.this,
list,
R.layout.listitem,
new String[]{"imageid","name","mobilephone"},
new int[]{R.id.user_image,R.id.tv_name,R.id.tv_mobilephone});
lv.setAdapter(adapter);//显示所有数据
mainMenuDialog.dismiss();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
confirmDialog.dismiss();
}
});
builder.create().show();
break;
}
case 2:{
mainMenuDialog.dismiss();
new AlertDialog.Builder(Main.this)
.setTitle("是否需要备份记录到SD卡?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
LayoutInflater li = LayoutInflater.from(Main.this);
View backup_view = li.inflate(R.layout.backup_progress, null);
progressDialog = new AlertDialog.Builder(Main.this)
.setTitle("备份正在进行中...")
.setView(backup_view)
.create();
progressDialog.show();
DBHelper helper = new DBHelper(Main.this);
helper.backupData(privacy);
ProgressBar bar = (ProgressBar) backup_view.findViewById(R.id.pb_backup);
Button btn_backup_ok = (Button)backup_view.findViewById(R.id.btn_backuup_ok);
bar.setMax(list.size());
for(int i=0;i<=list.size();i++) {
bar.setProgress(i);
}
progressDialog.setTitle("备份完成!一共 "+ list.size() + " 条记录");
btn_backup_ok.setVisibility(View.VISIBLE);
btn_backup_ok.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
progressDialog.dismiss();
mainMenuDialog.dismiss();
}
});
}
})
.setNegativeButton("取消", null)
.create()
.show() ;
break;
}
case 3:{
LayoutInflater li = LayoutInflater.from(Main.this);
View enterFileNameView = li.inflate(R.layout.enterfilename, null);
enterFileNameDialog = new AlertDialog.Builder(Main.this)
.setView(enterFileNameView).setNegativeButton("取消", null)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DBHelper helper = new DBHelper(Main.this);
fileName = et_enter_file_name.getText().toString();
if(helper.findFile(fileName)){
new AlertDialog.Builder(Main.this).setTitle("请选择方式")
.setPositiveButton("覆盖", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DBHelper helper = new DBHelper(Main.this);
helper.deleteAll(0);
helper.restoreData(fileName);
list = helper.getAllUser(privacy);
adapter = new SimpleAdapter(Main.this,
list,
R.layout.listitem,
new String[]{"imageid","name","mobilephone"},
new int[]{R.id.user_image,R.id.tv_name,R.id.tv_mobilephone});
LayoutInflater li = LayoutInflater.from(Main.this);
View backup_view = li.inflate(R.layout.backup_progress, null);
progressDialog = new AlertDialog.Builder(Main.this)
.setTitle("正在还原数据...")
.setView(backup_view)
.create();
progressDialog.show();
ProgressBar bar = (ProgressBar) backup_view.findViewById(R.id.pb_backup);
Button btn_backup_ok = (Button)backup_view.findViewById(R.id.btn_backuup_ok);
bar.setMax(list.size());
for(int i=0;i<=list.size();i++) {
bar.setProgress(i);
}
progressDialog.setTitle("还原完成!一共还原了 "+ list.size() + " 条记录");
btn_backup_ok.setVisibility(View.VISIBLE);
btn_backup_ok.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
progressDialog.dismiss();
mainMenuDialog.dismiss();
if(list.size() != 0) {
mainLinearLayout.setBackgroundDrawable(null);
}
lv.setAdapter(adapter);
}
});
}
})
.setNegativeButton("添加", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DBHelper helper = new DBHelper(Main.this);
int preNum = list.size();
helper.restoreData(fileName);
list = helper.getAllUser(privacy);
adapter = new SimpleAdapter(Main.this,
list,
R.layout.listitem,
new String[]{"imageid","name","mobilephone"},
new int[]{R.id.user_image,R.id.tv_name,R.id.tv_mobilephone});
LayoutInflater li = LayoutInflater.from(Main.this);
View backup_view = li.inflate(R.layout.backup_progress, null);
progressDialog = new AlertDialog.Builder(Main.this)
.setTitle("正在还原数据...")
.setView(backup_view)
.create();
progressDialog.show();
ProgressBar bar = (ProgressBar) backup_view.findViewById(R.id.pb_backup);
Button btn_backup_ok = (Button)backup_view.findViewById(R.id.btn_backuup_ok);
bar.setMax(list.size());
for(int i=0;i<=list.size();i++) {
bar.setProgress(i);
}
progressDialog.setTitle("还原完成!一共还原了 "+ (list.size()-preNum) + " 条记录");
btn_backup_ok.setVisibility(View.VISIBLE);
btn_backup_ok.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
progressDialog.dismiss();
mainMenuDialog.dismiss();
lv.setAdapter(adapter);
}
});
}
})
.setNeutralButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).create().show();
} else {
Toast.makeText(enterFileNameDialog.getContext(), "找不到备份文件", Toast.LENGTH_LONG).show();
}
}
})
.create();
et_enter_file_name = (EditText)enterFileNameView.findViewById(R.id.et_enter_file_name);
et_enter_file_name.setText("comm_data");
et_enter_file_name.requestFocus();
et_enter_file_name.selectAll();
enterFileNameDialog.show();
adapter = new SimpleAdapter(
Main.this,
list,
R.layout.listitem,
new String[]{"imageid","name","mobilephone"},
new int[]{R.id.user_image,R.id.tv_name,R.id.tv_mobilephone});
lv.setAdapter(adapter);//显示所有数据
mainMenuDialog.dismiss();
break;
}
长按联系人选项,会选中联系人,然后可以删除所选择的联系人,这个功能对于想删除多个联系人得时候比较方便,其如图5-5所示:
关键代码:
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_MENU) {
loadBottomMenu();
if(bottomMenuGrid.getVisibility() == View.VISIBLE) {
if(searchLinearout != null && searchLinearout.getVisibility() == View.VISIBLE) {
searchLinearout.setVisibility(View.GONE);
}
bottomMenuGrid.setVisibility(View.GONE);
} else {
bottomMenuGrid.setVisibility(View.VISIBLE);
}
}
return super.onKeyDown(keyCode, event);
}
private void loadBottomMenu() {
if(bottomMenuGrid == null) {
bottomMenuGrid = (GridView) findViewById(R.id.gv_buttom_menu);
bottomMenuGrid.setBackgroundResource(R.drawable.channelgallery_bg);
bottomMenuGrid.setNumColumns(5);
bottomMenuGrid.setGravity(Gravity.CENTER);
bottomMenuGrid.setVerticalSpacing(10);
bottomMenuGrid.setHorizontalSpacing(10); bottomMenuGrid.setAdapter(getMenuAdapter(bottom_menu_itemName,
bottom_menu_itemSource)); bottomMenuGrid.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
switch (arg2) {
case 0: {
if(searchLinearout != null && searchLinearout.getVisibility()==View.VISIBLE) {
searchLinearout.setVisibility(View.GONE);
}
if(bottomMenuGrid.getVisibility() == View.VISIBLE) {
bottomMenuGrid.setVisibility(View.GONE);
}
Intent intent = new Intent(Main.this,AddNew.class);
startActivityForResult(intent, 3);
break;
}
case 1:
loadSearchLinearout();
if(searchLinearout.getVisibility()==View.VISIBLE) {
searchLinearout.setVisibility(View.GONE);
} else {
searchLinearout.setVisibility(View.VISIBLE);
et_search.requestFocus();
et_search.selectAll();
}
break;
case 2:
if(searchLinearout != null && searchLinearout.getVisibility()==View.VISIBLE) {
searchLinearout.setVisibility(View.GONE);
}
if(deleteId == null || deleteId.size() == 0) {
Toast.makeText(Main.this, " 没有标记任何记录\n长按一条记录即可标记", Toast.LENGTH_LONG).show();
} else {
new AlertDialog.Builder(Main.this)
.setTitle("确定要删除标记的"+deleteId.size()+"条记录吗?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
DBHelper helper = new DBHelper(Main.this);
helper.deleteMarked(deleteId);
list = helper.getAllUser(privacy);
adapter =
new SimpleAdapter(
Main.this,
list,
R.layout.listitem,
new String[]{"imageid","name","mobilephone"},
new int[]{R.id.user_image,R.id.tv_name,R.id.tv_mobilephone});
lv.setAdapter(adapter);
deleteId.clear();
}
})
.setNegativeButton("取消", null)
.create()
.show() ;
}
break;
case 3:
if(searchLinearout != null && searchLinearout.getVisibility()==View.VISIBLE) {
searchLinearout.setVisibility(View.GONE);
}
loadMainMenuDialog();
mainMenuDialog.show();
break;
case 4:
finish();
break;
}
}
});
}
}
通过这次课程设计,我对Android程序设计有了新的认识,自己还有很多方面不足,但同时也弄懂了许多基础理论。在这个循序渐进的过程中,解决了一些自己的认为比较难的地方后我又继续朝前行进着, 我相信在下面的过程中我会越做越顺的。
课程设计终于在我的努力下做完了。这个时候我更加深入的了解了Java的特点以及一些相关知识。 与其临渊羡鱼,不如退而结网。这次Android课程设计给我的最大的印象就是如果自己有了兴趣,就动手去做,在你的勇气和毅力下,困难是抬不了头的。如果你连失败都不怕了,那你还怕什么,拾起懒惰的心,勤奋就会走向成功。这次的课程设计在我未来的时日里,是一个标杆,因为它告诉了我,只要我努力没有什么事我做不好的。
[1] 杨丰盛著.Android应用开发揭秘.北京:机械工业出版社,2011
[2] 百度文库中的关于Android应用平台与程序开发。
工程结构设计心得课程设计对学生而言是其对所学课程内容掌握情况的一次自我验证,从而有着极其重要的意义。通过课程设计能提高学生对所学知…
心得体会通过这次课程设计,让我更加深刻了解课本知识,和以往对知识的疏忽得以补充,在设计过程中遇到一些模糊的公式和专业用语,比如说经…
个人小结三周的课程设计结束了,我和同学们一起度过了这段忙碌而充实的时光。这次的课程设计深刻的反映出实践是检验真理的唯一标准这句话的…
通过近两周的奋斗,课程设计接近了尾声。经过两周的奋战我的课程设计终于完成了。在没有做课程设计以前觉得课程设计只是对信号与系统这门课…
课程设计心得体会通用通过此次课程设计使我更加扎实的掌握了有关方面的知识在设计过程中虽然遇到了一些问题但经过一次又一次的思考一遍又一…
Android应用设计实验报告学院:专业:通信工程班级:姓名:学号:100312107指导教师:20xx年x月x日天气查询1.关键…
软件学院课程设计报告20xx学年第二学期学院软件学院专业软件测试班级1班姓名汤微任课老师欧阳文臣2目录1课程设计概况12上课笔记摘…
安卓学生姓名学号专业班级设计题目学年学期指导教师课程设计简易计算器20xx20xx学年第一学期日期1签名目录第1章安卓应用程序开发…
安卓课程设计班级09级计算机二班学号20xx7923姓名郭丹1目录第1章安卓应用程序开发背景311开发背景312开发环境4第2章第…
《移动应用技术》课程设计报告题目:基于Android的金源书店库存管理系统的开发与设计学生姓名:专业:信息管理与信息系统班级:指导…