文档详情

Android应用案例课程设计报告

痛***
实名认证
店铺
DOC
5.52MB
约28页
文档ID:155489532
Android应用案例课程设计报告_第1页
1/28

Android应用案例课程设计文件状态:[ ] 草稿[√] 正式发布[ ] 正在修改项目名称:我的云账本文件标识:android_app-1当前版本:1.3.1作 者:燕学 号:31713109小组成员: 燕、正杰、德祥指导教师:史梦安完成日期:2015.7.2信息职业技术学院 计算机与通信工程学院版 本 历 史版本/状态作者参与者起止日期备注1.0.1燕马子璇2015.6.25代码完成1.1.1燕马子璇2015.6.27修改云存储的功能1.2.1燕马子璇2015.6.27优化界面以及功能1.3.1燕马子璇2015.7.2修改报告中的visio图表格名称各功能开发表序号功能子功能开发人员1主界面控制层〔事件等〕燕2显示层马子璇3账信息添加数据层〔Dao层〕马子璇4界面控制层燕5显示层马子璇6服务端燕7账信息查询统计数据层〔Dao层〕燕8界面控制层马子璇9显示层燕10服务端马子璇11账类型查看及修改数据层〔Dao层〕马子璇12界面控制层燕13显示层马子璇14服务端燕15账信息删除数据层〔Dao层〕燕16界面控制层马子璇17显示层燕18服务端马子璇19关于燕、马子璇-.一、前言记账软件记录着各种数据,如果软件一不小心删掉,所有数据就没有,就会觉得很可惜。

现在云盘普遍都支持接入应用本系统主要用于账信息的存储,主要通过移动数据网络或者WIFI,实现客户与服务端的云存储客户可以通过登录查询自己的账户信息二、系统分析2.1系统开发遵循的标准或规2.1.1 统一的开发平台移动端开发使用Eclipse4.3.2+AndroidSDK;服务端开发采用Eclipse4.3.2;移动端数据库开发采用SQLsever2.1.2 统一技术规总体上采用Java语言进行客户端及服务端的开发,移动客户端开发端采用Android开发技术规,系统静态及动态建模原那么上要求使用UML技术规2.2“云备忘录〞功能设计2.2.1本地备忘信息管理模块通过该模块的,用户可以完成对备忘信息的管理,主要功能包括:1.备忘信息添加,用户使用该功能可以完成对备忘信息的添加;2.备忘信息查询及统计,用户通过该功能完成对特定条件下的备忘信息的查询及统计工作,3.备忘信息查看及修改,用户通过该功能可以查看特定账信息的明细并可对其进行修改;4.备忘信息信息删除,用户可以删除特定账信息容〔只做逻辑删除,不做数据库层的物理删除,修改对应记录的status列数据,0表示不可用,1表示可用〕5.备忘信息提醒,用户添加完信息设置是否提醒,使用这个功能,用户可以在通知栏上看到提醒的信息。

6.备忘信息更新,点击更新按钮,用户可以更新状态,进行联网,使信息同步到数据库中2.2.1.1系统顶层用例图如图2.1:图2.1系统用例图2.2.1.2消费信息模型类类图如图2.2:图2.2 账信息类图2.2.2.信息的云存储的静态模型图智能 通过WIFI或者移动数据访问服务器,完成服务器与客户端的数据传输通过联网登录系统,添加信息,修改、删除信息,把信息发送到服务端,进行信息传输如图5—1网络拓扑图图5-1网络拓扑图联网以后,用户可以添加、查询、修改、删除、更新备忘信息,即使本地信息删除了,服务端还存有以前的信息,此功能可以防止信息的误删方便用户的使用,详细图解参照下列图图2-2系统用例图图2.2 系统活动图三、系统设计3.1系统采用的异步通信框架在Android2.3.3版本以后,所有联网操作不能在UI线程中进行必须在新建线程里进行网络连接,否那么将会抛出“NetworkOnMainThreadException〞异常而在Android系统中只能在主线程〔UI线程〕中对UI组件进行控制,如果通过子线程启动网络连接并对UI控件进行修改,这就需要与UI线程进行通信可以使用Handler类实现子线程与主线程的通信,为提高程序的健壮性,降低代码的耦合度,设计SocketProcessor类〔见附件1-6〕处理异步通信请求。

3.2系统初始化系统采用mysql数据库记录备忘信息,在移动端启动前需要进行数据库及数据表等的初始化3.1 系统初始化的动态模型启动程序后,获取备忘信息,生成备忘信息对象,存储在本地如果联网后,把信息序列化之后发送给服务端,服务端接收后,反序列化存储到云端,通过客户端解析响应判断有没有存储成功相关活动图如图3.1系统活动图:图 3.1 系统活动图3.2数据库设计系统采用SQLite关系型数据库进行数据库设计,由系统对象关系分析可知,系统数据存储结构如表一所示表1 备忘信息表表名note_info列名数据类型非空描述主键外键idint主键,自增Ynamevarchar(50)Y默认备忘名称datevarchar(50)Y日期workvarchar(50)Y容ischeckintegerYTrue成功false失败statusintegerY0标识不可用,1标识可用3.3主界面设计由于采用移动手持终端作为应用程序载体,为提高人机交互效果,主界面宜采用扁平化设计可以更加简单直接的将信息和事物的工作方式展示出来,减少认知障碍的产生主界面设计如图3.4所示图3.4 主界面设计3.5云同步设计由于用户在未联网状态时,账信息保存在本地数据库中,服务器是收不到任何数据,所以我们设计云同步功能,该功能主要是把本地数据与服务端同步,以便用户后期管理。

3.5.1采用的协议采用网络通信协议,运用第三方辅助工具JSON包,对数据序列化反序列化进行传输利用MyData类控制各种数据传输MyData类见图3.5.图3.5MyData类图3.5.2云同步动态模型获取本地数据库数据,对每条数据进行序列化,将序列化字符串发送到服务器,服务器接收字符串,进行反序列化解析,并且与服务器中数据进行对比,如果此条数据在服务器中没有表达,那么保存在数据库中,整个数据遍历完毕,响应本次操作,客户端接收响应,同步完成动态图如下列图3.5.2图3.5.2 云同步动态模型3.5.3序列化反序列化关键代码序列化:MyData response = new MyData(); response.type = CommonData.ResponseType.ADD_notepad; response.data = ni; response.status = "ok";return JSON.toJSON(response).toString();反序列化:MyData md = JSON.parseObject(data, new TypeReference>(){});String type = md.type; System.out.println("接收请求:"+data);//由于不知道何种请求,首选将JSON字符串反序列化为MyData对象//判断请求类型,根据不同的请求类型,重新反序列化JSON字符串四、系统实现4.1 数据库存储系统的实现本存储系统利用Andorid的SQLSever关系型数据库存储系统实现。

其数据表字段及数据表创建等核心代码如下所示:数据存储代码:客户端://账信息数据表相关字段publicfinal String TNAME_1 = "account_info";publicfinal String COLUMN1_1 = "account_type";publicfinal String COLUMN2_1 = "account";publicfinal String COLUMN3_1 = "account_remark";publicfinal String COLUMN4_1 = "account_date";publicfinal String COLUMN5_1 = "account_record_time";publicfinal String COLUMN6_1 = "type";//账信息类型,1表示入账,-1表示出账publicfinal String COLUMN7_1 = "status";//记录状态,1表示可用,0表示不可用 //账信息数据表相关字段publicfinal String TNAME_2 = "account_type_info";publicfinal String COLUMN1_2 = "account_type_name";publicfinal String COLUMN2_2 = "account_type_remark";publicfinal String COLUMN3_2 = "account_type_time";//录入到数据库中的时间publicfinal String COLUMN4_2 = "type";//账类型信息对应的类型,-1表示消费(出账),1表示收入(入账)publicfinal String COLUMN5_2 = "status";//记录状态mSQLiteDB.execSQL("create table if not exists " + TNAME_1 + " (" + _ID + " integer primary key AUTOINCREMENT," + COLUMN1_1 + " integer," + COLUMN2_1 + " text," + COLUMN3_1 + " text, "+COLUMN4_1+" date," + COLUMN5_1 + " time, "+COLUMN6_1+" integer,"+COLUMN7_1+" integer)"); mSQLiteDB.execSQL("create table if not exists " + TNAME_2 + " (" + _ID + " integer primary key AUTOINCREMENT," + COLUMN1_2 + " text," + COLUMN2_2 + " text," + COLUMN3_2 + " time," + COLUMN4_2 + " integer, "+ COLUMN5_2 + " integer)"); mSQLiteDB.close();服务端:public static boolean addAccountInfo(AccountInfo ai){ new SMADao_up().upData("insert into account_type_info values(",",",",",",",",")", new Object[]{ null, ai.getAccountType().getId(), ai.getAccount(), ai.getAccountRemark()+"", ai.getAccountDate(), ai.getUserInfo().getId(), ai.getNativeId(), ai.getDeviceId(), ai.getStatus()}); return true; }4.2 系统功能实现4.2.1本地账类型管理用户登陆后可进行在已有的账类型基础下可以添加账信息。

点击主界面的查询按钮弹出对话框,可以按查询条件查询账类型对应的账项目信息,选择查看可以查看具体信息,并对他进行修改点击删除可进行删除点击添加按钮可以添加账项目4.2.1.1账类型管理显示效果用户登录后可以添加信息如4.1添加显示效果,可以点击主页面的查询按钮弹出对话框,在对话框里进行查询和修改如4.1查询显示效果和4.1修改显示效果4.1添加显示效果 4.1查询显示效果 4.1修改显示效果4.2 .1.2相关核心代码chaxun.setOnClickListener(new OnClickListener() { Override public void onClick(View arg0) { // TODO Auto-generated method stub String zhanglx = zhang_leixing.getSelectedItem().toString().trim(); if(zhanglx.startsWith("出账")){ queryAccountType_ = (Vector) new AccountDao(context) .findAccountTypeByType(-1); ala .notifyDataSetInvalidated(); }else if(zhanglx.startsWith("入账")){ queryAccountType_ = (Vector) new AccountDao(context) .findAccountTypeByType(1); ala .notifyDataSetChanged(); } } }); //添加按钮事件 add.setOnClickListener(new OnClickListener() { Override public void onClick(View arg0) { // TODO Auto-generated method stub new SetAddDialog(context).showDialog(); } }); set_List.setOnItemLongClickListener(new OnItemLongClickListener() { Override public boolean onItemLongClick(AdapterView<"> arg0, View arg1, int pos, long arg3) { final int posi = pos; // TODO Auto-generated method stub new ModifyChoosenDialog(context){ public void itemEvent(DialogInterface arg0, int pos) { // TODO Auto-generated method stub super.itemEvent(arg0, pos); CommonData.acc = queryAccountType_.elementAt(posi); String text = (String) this.items[pos]; if (text.equals("查看")) { new ZChakanDialog(context){ public void onCancel(DialogInterface arg0) { chaxun.performClick(); }; }.showDialog();}else if(text.equals("删除")){new AlertDialog.Builder(context).setTitle("确认删除").setPositiveButton("确定",// 设置确定按钮,第二个参数是传事件对象 new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog,int whichButton) { // 删除操作 if(CommonData.acc.getId() < 7){Toast.makeText(context,"删除失败,默认类型无法删除",Toast.LENGTH_LONG).show(); }else{ new AccountDao(context).deleteAccountType_(CommonData.acc.getId());Toast.makeText(context,"删除成功",Toast.LENGTH_LONG).show(); } } }).setNeutralButton("取消", null).show(); } this.dismiss(); } }.showSingleChoiceDialog(); return false; } }); }4.2.2用户注册及登录功能将用户的信息添加到数据库中,先进行用户注册,把用户信息添加到数据库中,注册时假设数据数据库中没有数据那么注册,然后点击菜单中的登陆按钮,就可以显示登陆成功。

然后就可以进行用户的信息添加查询之类的操作4.2.2.1 用户登录动态模型打开主页面的菜单,点击菜单中的注册按钮,就可以使用用户注册的功能,注册成功之后,返回,点击菜单中的登陆按钮,就可以成功的登陆接着就可以添加信息,修改信息,生成请求对象,序列化反序列化之后,可以存储到服务端服务端通过客户端的响应判断是否同步到服务端如下列图,图4.2.2.1用户登录动态图活动动态图: 图4.2.2.1用户登录动态图4.2.2.2 登录界面效果 1.进入主页面,打开注册系统,先进行注册,注册成功之后点击登陆按钮就可以登陆了如图2-2-1所示图2-2-1 主界面菜单 图2-2-2注册窗口 图2-2-3登录窗口 相4.2.2.3关核心代码//发送登录请求的编码如下所示://获取用户数据,封装成json,发送 String name = nameEdit.getText().toString().trim(); String pass = passEdit.getText().toString().trim(); UserInfo user = new UserInfo(); user.setUserName(name); user.setUserPass(pass); MyData request = new MyData(); request.type = CommonData.RequestType.LOGIN; request.data = user; request.status = "ok"; String request_ = JSON.toJSON(request).toString(); SocketProcessor.sendData(request_);//处理用户登录响应的Handler编码如下所示_response_login_handler = new Handler(){ Overridepublicvoid handleMessage(Message msg) { // TODO Auto-generated method stubsuper.handleMessage(msg); String data = msg.getData().getString(SocketProcessor.KEY); MyData md_ = JSON.parseObject(data, new TypeReference>(){});if(md_.status.equals("ok")){ CommonData.login_user = md_.data; userText.setText("用户:"+md_.data.getNickName()); loginDialog.dismiss(); }elseif(md_.status.equals("notok")){ showToast("用户名、密码错误!"); } } };服务端关键代码:if(type.equals(CommonData.RequestType.LOGIN)){ //JSON. MyData md_ = JSON.parseObject(data, new TypeReference>(){}); String name = md_.data.getUserName(); String pass = md_.data.getUserPass(); System.out.println("用户名:"+name+" 密码:"+pass); UserInfo user = UserInfoDao.findUserInfoByNamePass(name, pass);if(user != null){//合法用户 MyData response = new MyData(); response.type = CommonData.ResponseType.LOGIN; response.data = user; response.status = "ok"; Server.userMap.put(socket, user);//将合法用户记录下来return JSON.toJSON(response).toString(); }else{ MyData response = new MyData(); UserInfo u = new UserInfo(); u.setId(-1); u.setNickName(""); u.setUserName(name); u.setUserPass(pass); response.type = CommonData.ResponseType.LOGIN; response.data = u; response.status = "notok";return JSON.toJSON(response).toString(); } }2、输入用户名和密码后,可进入本用户对应的系统。

用户名和密码如表1所示,第一个为默认的用户,软件自动添加该用户名信息,用户名和密码区分大小写:表1 系统初始用户名密码序号身份用户名密码1默认用户weiyan1232普通用户用户名密码4.2.3账信息云管理这个功能主要是用户出入账信息的管理,点击主界面的添加按钮,打开出入账信息添加对话框,选择账类型〔出账还是入账〕及账目项,输入金额、出入账日期以及备注等信息后点击“添加〞按钮将信息录入数据库中当录入成功后“添加〞按钮不能用,点击“继续添加〞按钮,就可以继续添加数据查询功能主要实现数据的查询,点击主界面的查询按钮,选择查询条件,出〔如〕账,日期,类型,查询方式,点击查询按钮,长按查询的信息可以出现一个对话框,点击查看弹出对话框可以查看信息的主要容,并可以点击修改按钮对信息进行修改点击删除可以对数据进行删除4.2.3.1账信息管理效果图1.账信息添加用户可自己进行信息的添加,添加操作方式在主界面中点击添加图片按钮如图3-1-1所示,进入添加界面,如图3-1-2所示,输入数据,添加成功后会显示“添加成功〞,如图3-1-3所示图3-1-1 主界面按钮 图3-1-2 添加对话框 图3-1-3 添加成功2.账信息查询查询界面,点击查询按钮,如图3-2-1所示,查询符合条件的数据,查询结果进入如图3-2-2所示。

图3-2-2主界面 图3-2-2 查询 图3-2-3查询结果3.账类型设置点击主界面设置按钮,如图3-3-1所示,进入账类型管理界面,点查询按钮查询账类,查询结果为3-3-2所示图3-3-1 主界面 图3-3-2 账类型查询结果4.2.3.2核心代码:addBtn.setOnClickListener(new OnClickListener() { Override public void onClick(View v) { // TODO Auto-generated method stub //获取账信息 String zhangType = typeSpinner.getSelectedItem().toString(); AccountType at = (AccountType)accountTypeSpinner.getSelectedItem();// int accountId = ((AccountType)accountTypeSpinner.getSelectedItem()).getId();//出入账类型id String account = accountEdit.getText().toString().trim(); String accountRemark = accountRemarkEdit.getText().toString().trim(); String date = dateEdit.getText().toString().trim(); if(account.length() == 0){ Toast.makeText(context, "信息不完整", Toast.LENGTH_LONG).show(); return; } AccountInfo ai = new AccountInfo(); ai.setAccount(account); ai.setAccountDate(date); ai.setAccountRecordTime(CommonUtils.getTime(new Date())); ai.setAccountRemark(accountRemark); ai.setStatus(1); if(zhangType.trim().startsWith("出账")){ ai.setType(-1);// ai.setAccountType(new AccountDao(context).findAccountTypeById(accountId)); ai.setAccountType(at); }else if(zhangType.trim().startsWith("入账")){ ai.setType(1);// ai.setAccountType(new AccountDao(context).findAccountTypeById(accountId)); ai.setAccountType(at); } //生成账信息本地id〔移动端SQLite〕 String id = new AccountDao(context).addAccountInfo(ai); if(id != null){ Toast.makeText(context, "信息添加成功", Toast.LENGTH_LONG).show(); addBtn.setEnabled(false); accountEdit.setEnabled(false); accountRemarkEdit.setEnabled(false); conAddBtn.setEnabled(true); //判断当前用户是否登录,网络是否连通 if(SocketProcessor.isConnected() && CommonData.login_user!=null){ ai.setId("1");//修改id防止服务端解析异常 ai.setNativeId(id); ai.setDeviceId(CommonData.device_id);//添加手持设备号 ai.setUserInfo(CommonData.login_user); MyData request = new MyData(); request.type = CommonData.RequestType.ADD_ACCOUNT; request.data = ai; request.status = "ok"; String request_ = JSON.toJSON(request).toString(); SocketProcessor.sendData(request_); } } } });账信息查询:queryBtn.setOnClickListener(new OnClickListener() { Override public void onClick(View v) { // TODO Auto-generated method stub String date = dateEdit.getText().toString();//查询日期 int query = queryTypeSpinner.getSelectedItemPosition();//查询方式,查询的日期方式 String zhanglx = zhanglxSpinner.getSelectedItem().toString().trim();//选择的是出账、入账还是所有 if(zhanglx.startsWith("所有")){Log.e("zdx", date+"-"+query); queryAccountInfos = new AccountDao(QueryActivity.this).findAllAccountInfoByQueryType(date, query); Log.e("zdx", queryAccountInfos+""); ala.notifyDataSetInvalidated(); }else if(zhanglx.startsWith("出账")){ AccountType at_chosen = (AccountType)accountTypeSpinner.getSelectedItem(); int typeId = at_chosen.getId(); queryAccountInfos = new AccountDao(QueryActivity.this).findAccountInfoByAccountType(typeId, date, query, -1); Log.e("sss", queryAccountInfos.toString()); ala.notifyDataSetInvalidated(); }else if(zhanglx.startsWith("入账")){ AccountType at_chosen = (AccountType)accountTypeSpinner.getSelectedItem(); int typeId = at_chosen.getId(); queryAccountInfos = new AccountDao(QueryActivity.this).findAccountInfoByAccountType(typeId, date, query, 1); ala.notifyDataSetInvalidated(); } double total = 0.0; for(int i=0;i arg0, View arg1, int pos, long arg3) { // TODO Auto-generated method stub //设置公共数据区的选中账信息对象 CommonData.choosenAccountInfo = (AccountInfo)queryAccountInfos.elementAt(pos);// Log.e("smax", CommonData.choosenAccountInfo.getAccountRemark()); new ModifyChoosenDialog(QueryActivity.this){ Override public void itemEvent(DialogInterface arg0, int pos) { // TODO Auto-generated method stub super.itemEvent(arg0, pos); String text = (String)this.items[pos]; if(text.startsWith("查看")){ new DetailDialog(QueryActivity.this){ public void onCancel(DialogInterface dialog) { /*******************************/ String date = dateEdit.getText().toString();//查询日期 int query = queryTypeSpinner.getSelectedItemPosition();//查询方式 String zhanglx = zhanglxSpinner.getSelectedItem().toString().trim();//选择的是出账、入账还是所有 if(zhanglx.startsWith("所有")){ queryAccountInfos = new AccountDao(QueryActivity.this).findAllAccountInfoByQueryType(date, query); ala.notifyDataSetInvalidated(); }else if(zhanglx.startsWith("出账")){ AccountType at_chosen = (AccountType)accountTypeSpinner.getSelectedItem(); int typeId = at_chosen.getId(); queryAccountInfos = new AccountDao(QueryActivity.this).findAccountInfoByAccountType(typeId, date, query, -1); ala.notifyDataSetInvalidated(); }else if(zhanglx.startsWith("入账")){ AccountType at_chosen = (AccountType)accountTypeSpinner.getSelectedItem(); int typeId = at_chosen.getId(); queryAccountInfos = new AccountDao(QueryActivity.this).findAccountInfoByAccountType(typeId, date, query, 1); ala.notifyDataSetInvalidated(); } double total = 0.0; for(int i=0;i{ public String type; public T data; public String status;}public class Test { public static void main(String[] args) { String json_data = "{\"data\":{\"id\":1,\"userName\":\"abc\",\"userPass\":\"123\"},\"type\":\"_request_login\"}"; MyData md = JSON.parseObject(json_data, new TypeReference>(){}); MyData _md_x = JSON.parseObject(json_data, new TypeReference>(){}); System.out.println(_md_x.data.getUserName()); }}账信息添加:public static boolean addAccountInfo(AccountInfo ai){ new SMADao_up().upData("insert into account_type_info values(",",",",",",",",")", new Object[]{ null, ai.getAccountType().getId(), ai.getAccount(), ai.getAccountRemark()+"", ai.getAccountDate(), ai.getUserInfo().getId(), ai.getNativeId(), ai.getDeviceId(), ai.getStatus()}); return true; }账信息查询:public static Vector findAllAccountInfo() { Vector va = new Vector(); Vector vv = new SMADao_up().DBQuery ("select * from account_type_info", null); for(int i=0;i vv = new SMADao_up().DBQuery("select * from account_type_info where _id="", new Object[]{id});// if(vv.size()>0){// at.setAccountTypeName(vv.elementAt(0).elementAt(1).toString());// at.setAccountTypeRecordTime(vv.elementAt(0).elementAt(3).toString());// at.setAccountTypeRemark(vv.elementAt(0).elementAt(2).toString());// at.setId(Integer.parseInt(vv.elementAt(0).elementAt(0).toString()));// a。

下载提示
相关文档
正为您匹配相似的精品文档