Android应用案例课程设计

上传人:沈*** 文档编号:203028139 上传时间:2023-04-23 格式:DOC 页数:27 大小:5.56MB
返回 下载 相关 举报
Android应用案例课程设计_第1页
第1页 / 共27页
Android应用案例课程设计_第2页
第2页 / 共27页
Android应用案例课程设计_第3页
第3页 / 共27页
点击查看更多>>
资源描述
淮信学习论坛项目设计报告Android应用案例课程设计文件状态: 草稿 正式发布 正在修改项目名称:我的云账本文件标识:android_app-1当前版本:1.3.1作 者:学 号:小组成员: 指导教师:完成日期:2015.7.2淮安信息职业技术学院 计算机与通信工程学院版 本 历 史版本/状态作者参与者起止日期备注1.0.12015.6.25代码完成1.1.12015.6.27修改云存储的功能1.2.12015.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关于 淮安信息职业技术学院,2014Page 27 of 27一、前言记账软件记录着各种数据,如果软件一不小心删掉,所有数据就没有,就会觉得很可惜。现在云盘普遍都支持接入应用。本系统主要用于账信息的存储,主要通过移动数据网络或者WIFI,实现客户与服务端的云存储。客户可以通过登录查询自己的账户信息。二、系统分析2.1系统开发遵循的标准或规范2.1.1 统一的开发平台移动端开发使用Eclipse4.3.2+AndroidSDK;服务端开发采用Eclipse4.3.2;移动端数据库开发采用SQLsever。2.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或者移动数据访问服务器,完成服务器与客户端的数据传输。通过联网登录系统,添加信息,修改、删除信息,把信息发送到服务端,进行信息传输。如图51网络拓扑图。 图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 TypeReferenceMyData(); String type = md.type;System.out.println(接收请求:+data);/由于不知道何种请求,首选将JSON字符串反序列化为MyData对象/判断请求类型,根据不同的请求类型,重新反序列化JSON字符串四、系统实现4.1 数据库存储系统的实现本存储系统利用Andorid的SQLSever关系型数据库存储系统实现。其数据表字段及数据表创建等核心代码如下所示:数据存储代码:客户端: /账信息数据表相关字段public final String TNAME_1 = account_info;public final String COLUMN1_1 = account_type;public final String COLUMN2_1 = account;public final String COLUMN3_1 = account_remark;public final String COLUMN4_1 = account_date;public final String COLUMN5_1 = account_record_time;public final String COLUMN6_1 = type;/账信息类型,1表示入账,-1表示出账public final String COLUMN7_1 = status;/记录状态,1表示可用,0表示不可用/账信息数据表相关字段public final String TNAME_2 = account_type_info;public final String COLUMN1_2 = account_type_name;public final String COLUMN2_2 = account_type_remark;public final String COLUMN3_2 = account_type_time;/录入到数据库中的时间public final String COLUMN4_2 = type;/账类型信息对应的类型,-1表示消费(出账),1表示收入(入账)public final 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 Objectnull,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() Overridepublic void onClick(View arg0) / TODO Auto-generated method stubString 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() Overridepublic void onClick(View arg0) / TODO Auto-generated method stubnew SetAddDialog(context).showDialog(););set_List.setOnItemLongClickListener(new OnItemLongClickListener() Overridepublic boolean onItemLongClick(AdapterView arg0, View arg1,int pos, long arg3) final int posi = pos;/ TODO Auto-generated method stubnew ModifyChoosenDialog(context)public void itemEvent(DialogInterface arg0, int pos) / TODO Auto-generated method stubsuper.itemEvent(arg0, pos);CommonData.acc = queryAccountType_.elementAt(posi);String text = (String) this.itemspos;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()Overridepublic void handleMessage(Message msg) / TODO Auto-generated method stubsuper.handleMessage(msg);String data = msg.getData().getString(SocketProcessor.KEY);MyData md_ = JSON.parseObject(data, new TypeReferenceMyData();if(md_.status.equals(ok)CommonData.login_user = md_.data;userText.setText(用户:+md_.data.getNickName();loginDialog.dismiss();else if(md_.status.equals(notok)showToast(用户名、密码错误!);服务端关键代码:if(type.equals(CommonData.RequestType.LOGIN)/JSON.MyData md_ = JSON.parseObject(data, new TypeReferenceMyData();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();elseMyData 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() Overridepublic 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();/出入账类型idString 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() Overridepublic void onClick(View v) / TODO Auto-generated method stubString 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;iqueryAccountInfos.size();i+)AccountInfo ai = queryAccountInfos.elementAt(i);double account = Double.parseDouble(ai.getAccount();Log.e(zdx, ai+);total += ai.getType()*account;totalText.setText(总计:+total););账信息查看修改:accountList.setOnItemLongClickListener(new OnItemLongClickListener() Overridepublic boolean onItemLongClick(AdapterView 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)Overridepublic void itemEvent(DialogInterface arg0, int pos) / TODO Auto-generated method stubsuper.itemEvent(arg0, pos);String text = (String)this.itemspos;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;iqueryAccountInfos.size();i+)AccountInfo ai = queryAccountInfos.elementAt(i);double account = Double.parseDouble(ai.getAccount();Log.e(zdx, ai+);total += ai.getType()*account;totalText.setText(总计:+total);/*/;.showDialog();else if(text.startsWith(删除)new AccountDao(QueryActivity.this).deleteAccountInfo(CommonData.choosenAccountInfo.getId();this.dismiss();.showSingleChoiceDialog();return false;);服务端关键代码:public class MyDatapublic 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 TypeReferenceMyData();MyData _md_x = JSON.parseObject(json_data, new TypeReferenceMyData();System.out.println(_md_x.data.getUserName();账信息添加:public static boolean addAccountInfo(AccountInfo ai)new SMADao_up().upData(insert into account_type_info values(?,?,?,?,?,?,?,?,?), new Objectnull,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;ivv.size();i+)AccountInfo ai = new AccountInfo();ai.setAccountType(findAccountTypeById(Integer.parseInt(vv.elementAt(i).elementAt(1).toString();ai.setAccount(vv.elementAt(i).elementAt(2).toString();ai.setAccountRemark(vv.elementAt(i).elementAt(3).toString();ai.setAccountDate(vv.elementAt(i).elementAt(4).toString();ai.setNativeId(vv.elementAt(i).elementAt(6).toString();ai.setDeviceId(vv.elementAt(i).elementAt(7).toString();ai.setStatus(Integer.parseInt(vv.elementAt(i).elementAt(8).toString();va.addElement(ai);return va;public static AccountType findAccountTypeById(int id)AccountType at = new AccountType();/Vector vv = new SMADao_up().DBQuery(select * from account_type_info where _id=?, new Objectid);/if(vv.size()0)/at.setAccountTypeName(vv.elementAt(0).elementAt(1).
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!