1. 前言:2017年学了一个月Android后写的小项目,文档近日才完成,项目与文档均为原创,发布出来以此怀念一下几年前。由于2017年写的项目,代码与技术均落后,但能提供下编写类似项目一点思路以及课程设计文档的编写。
2.项目链接:Android-QQ-课程设计(源码+论文)-Android文档类资源-CSDN下载
3. 项目视频:Android-QQ 仿QQApp_哔哩哔哩_bilibili
4. 项目功能简述
Web服务器采用struts2、hibernate、spring框架,使用Mysql数据库存储数据
在Android中 调用 URL进行后台访问靠JSON传值,进行仿QQ的一个开发,完成聊天,好友,动态这三个功能。
- 用户模块:用户登录注册、头像图片选择、个人信息、修改资料
- 好友模块:好友列表、好友添加、好友删除、好友移动分组、好友资料
- 聊天模块:发送接受消息
- 动态模块:查看好友的动态、发表自己的动态
5. 项目文档如下
?
目录
一、绪 论... 2
1.1研究的背景及意义... 2
1.2本文主要内容... 2
二、相关技术和开发环境... 2
2.1关键技术... 2
2.1.1Struts2. 2
2.1.2Hibernate.. 3
2.1.3Spring.. 3
2.1.3android-async-http. 3
2.2 开发环境及平台... 3
2.2.1Eclipse. 3
2.2.2Tomcat服务器... 4
2.2.3应用平台Android. 4
三、系统分析与设计... 5
3.1需求分析... 5
3.1.1系统目标和要求... 5
3.1.2可行性分析... 5
3.2 系统概要设计... 5
3.2.1模块的划分... 5
3.2.2移动端功能模块的设计... 5
3.3 数据库设计... 7
3.3.1数据库需求分析... 7
3.3.2数据库E-R图设计... 7
3.3.3数据表设计... 9
四、系统实现... 11
4.1安卓平台系统实现... 11
4.1.1功能描述... 11
4.1.2程序运行效果... 11
4.1.3功能概括和关键代码... 31
4.2服务器端的实现概括... 45
五、结? 论.... 46
1.1研究的背景及意义
???? ?即时通讯软件是受人们所需求而产生的,早在古代便有飞鸽传书来传递信息,再到电报、邮件信封,人与人之间的通信发展是必要的,通信软件的产生使人与人之间的距离更短,即时相隔千里,也能传达彼此的思念。通信软件比飞鸽传书快,比电报易读,比信封邮件简短,是传递信息的好帮手。
本文介绍了系统的开发过程。论文详尽论述了从需求分析、系统分析、概要设计、详细设计以及测试与调试的整个开发过程。首先系统地研究了系统的背景和意义。接着介绍了实现系统开发的Android平台环境,数据库SqlServer实现。同时简要介绍了以上工具的功能和方法。
概要设计主要讲解客户端操作设计,同时介绍了数据库的建立和维护。详细设计主要阐述了用户管理、好友管理、聊天管理、动态管理等实现,并给出了系统的部分设计代码。
2.1关键技术
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着非常大的变化,但是相对于WebWork,Struts 2的变化很小。
Hibernate,是负责了跟数据库的交接。通过持久化数据对象,进行对象关系的映射,并以对象的角度来访问数据库。通过封装JDBC,使得开发人员可以以面向对象编程的思想来操控数据库,从而摆脱了以往使用JDBC编程时的“死板”操作。通过hibernate.cfg.xml文件来取代以往的JDBC连接数据库的一大串代码,通过XXX(实体Bean的类名).hbm.xml文件来与数据库的具体表进行映射。并且Hibernate有自己的HQL语句,与数据库的SQL语句相似,但不同的是HQL语句在面向对象编程的角度上,通过Session的createQuery方法创建户一个query对象,由这个对象来完成对数据库的增删改查等操作。通过Struts2中Action的返回值,来调用Dao层中的业务处理。
Spring,使用基本的实体JavaBean来完成以前只能用EJB完成的事情。而其核心则是控制反转(IOC)和面向切面编程(AOP)。使用Spring,意味着一个对象的创建再也不是自己new出来的,而是全权交给了IOC容器去实例化。与此同时,Spring通过采用依赖注入(DI)的方式,通过属性的Setter和Getter方法来注入这个对象的属性,这样的好处就是不完全依赖于容器的API,且查询依赖与代码实现了解耦。而AOP,则是将应用的业务逻辑和系统级服务(例如事务)分离开来,进行内聚性的开发,应用对象只负责完成业务逻辑而不关心日志或者事务的处理。?
2.1.3android-async-http
移动端使用android-async-http 开源框架可以使我们轻松地获取网络数据或者向服务器发送数据,最关键的是,它是异步框架,在底层使用线程池处理并发请求,效率很高,使用又特别简单。
2.2 开发环境及平台
Eclipse是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse附带了一个标准的插件集,包括Java开发工具(Java Development Tools,JDT)。Eclipse是著名的跨平台的自由集成开发环境(IDE)。最初主要用来Java语言开发,但是目前亦有人通过插件使其作为其他计算机语言比如C++和Python的开发工具。Eclipse的本身只是一个框架平台,但是众多插件的支持使得Eclipse拥有其他功能相对固定的IDE软件很难具有的灵活性。许多软件开发商以Eclipse为框架开发自己的IDE。
Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为比较流行的Web 应用服务器。
2.2.3应用平台Android
安卓(Android)是一种基于Linux内核(不包含GNU组件)的自由及开放源代码的操作系统。主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发。Android操作系统最初由Andy Rubin开发,主要支持手机。2005年8月由Google收购注资。2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。随后Google以Apache开源许可证的授权方式,发布了Android的源代码。第一部Android智能手机发布于2008年10月。Android逐渐扩展到平板电脑及其他领域上,如电视、数码相机、游戏机、智能手表等。2011年第一季度,Android在全球的市场份额首次超过塞班系统,跃居全球第一。 2013年的第四季度,Android平台手机的全球市场份额已经达到78.1%。2013年09月24日谷歌开发的操作系统Android在迎来了5岁生日,全世界采用这款系统的设备数量已经达到10亿台。
三、系统分析与设计
首先,我们得确定使用这个系统是用户进行操作。用户是整个系统的核心,一切功能由用户操作发生,然后系统进行处理;通信目的是重点,所以需要达到以下要求。
- 最重要的是两个用户能进行沟通对话,并且页面操作简单、界面友好:完全控件式的页面布局,展示聊天信息。
- 即时可见:用户发送消息另一方接受应该不能太长
除了聊天外,应该要增加动态模块,好友管理模块来增强系统完整
此次毕业设计基于Android平台开发通信系统。Android平台给我们提供了巨大的自由空间,再运用Java面向对象语言,是系统功能更加强大。SqlServer 是一个杰出的数据库平台,具有功能强大,安全可靠等特点,可用于中小型联机事务处理、数据仓库及电子商务等。
3.2 系统概要设计
系统的概要设计主要对系统的总体功能如何设计,如何划分模块,系统的数据库如何设计进行研究。它为系统的详细设计做铺垫。在系统的设计过程中起着非常重要的作用。
本系统主要分两部分:
1.Web系统提供数据给移动端
2.移动端进行具体的操作。能注册、登录、查询好友、添加删除好友、与好友聊天、动态查看、发表动态等功能
1.总体设计
移动端主要有以下几个模块构成:用户信息、聊天功能、好友管理、动态等功能
2.详细功能设计
???????? ?安卓通讯系统以用户个人为主题,因此需要一个用户表来保存用户信息。所以用编号做主键。用户需要在系统上聊天的对象所以需要一个用户表来保存用户的好友。用户有了聊天对象需要具体的聊天,所以需要一个来保存聊天内容的表。为了增加系统的完善性,需要一个好友之间能互相发动态说说来表明自己此时心情状态的空间功能,所以需要一个动态表。
数据库的概念设计,即利用数据模型进行概念数据库的模式设计。根据安卓通讯系统的需求,设计出以下的实体-关系模型(E-R)图如图。
图3-3 实体联系图
????????????????????????????????????????????????????????????????图3-4 实体联系图
图3-5 实体联系图
数据库的逻辑设计,即把概念设计得到的概念数据库模式变为逻辑数据模式,它依赖于DBMS。根据安卓通讯系统的分析及数据库的概念设计,建立数据库了androidqqdata。
建库语句:create database androidqqdata;
设计表结构,如下图所示:
表3.1 用户信息表(android_qq_user)
列名 | 数据类型 | 是否允许为空 | 说明 | qq_id | int | 否 | 序号(主键) | qq_zhanghao | varchar(15) | 否 | 账号 | qq_mima | varchar(11) | 否 | 密码 | qq_touxiang | varchar(100) | 是 | 头像 | qq_name | varchar(20) | 是 | 昵称 | qq_mark | varchar(100) | 是 | 个性签名 | qq_sex | varchar(2) | 是 | 性别 | qq_address | varchar(80) | 是 | 地址 | qq_phone | varchar(11) | 是 | 电话 | qq_statu | Int | 是 | 0下线、1上线 |
表3.2 好友信息表(android_qq_hy)
列名 | 数据类型 | 是否允许为空 | 说明 | hy_id | int | 否 | 序号(主键) | myqq_id | int | 是 | 我的id编号 | myqq_zhanghao | varchar(15) | 是 | 我的账号 | myqq_name | varchar(20) | 是 | 我的昵称 | myqq_fengzu | int | 是 | 我的分组 | hyqq_id | int | 是 | 好友id编号 | hyqq_zhanghao | varchar(15) | 是 | 好友账号 | hyqq_name | varchar(20) | 是 | 好友昵称 | hyqq_statu | Int | 是 | 好友的分组 |
表3.3 消息表(android_qq_message)
列名 | 数据类型 | 是否允许为空 | 说明 | m_id | int | 否 | 序号(主键) | qq_id | int | 是 | 发送者ID | qq_zhanghao | varchar(15) | 是 | 发送者账号 | qq_name | varchar(20) | 是 | 发送者昵称 | m_message | varchar(200) | 是 | 消息内容 | m_date | datetime | 是 | 发送者时间 | m_jsid | Int | 是 | 接受者ID | m_zhanghao | varchar(15) | 是 | 接受者账号 | m_name | varchar(20) | 是 | 接受者昵称 |
表3.4展示消息表(android_qq_dynamic)
列名 | 数据类型 | 是否允许为空 | 说明 | sm_id | int | 否 | 序号(主键) | qq_id | int | 是 | Qqid | qq_zhanghao | varchar(15) | 是 | Qq账号 | qq_name | varchar(20) | 是 | 昵称 | qq_touxiang | varchar(100) | 是 | 头像 | hy_id | Int | 是 | 好友id | hy_zhanghao | varchar(15) | 是 | 好友账号 | hy_name | varchar(20) | 是 | 好友昵称 | hy_touxiang | varchar(100) | 是 | 好友头像 | sm_content | varchar(100) | 是 | 消息内容 | sm_date | datetime | 是 | 发送时间 |
表3.5动态表(android_qq_dynamic)
列名 | 数据类型 | 是否允许为空 | 说明 | dy_id | int | 否 | 序号(主键) | qq_id | int | 是 | Qqid | qq_zhanghao | varchar(15) | 是 | Qq账号 | qq_name | varchar(20) | 是 | 昵称 | dy_date | Datetime | 是 | 发表日期 | dy_content | varchar(500) | 是 | 发表内容 | dy_photos | varchar(500) | 是 | 发表图片 |
4.1安卓平台系统实现
整个项目功能完善,包含登录注册、好友列表、好友信息、搜索好友、添加删除好友、与好友聊天、好友动态等几个功能模块。每个模块组成整个系统功能,功能完善,具有真正QQ的功能。
注册界面主要来注册登录用户,是用来实现后续好友、聊天、搜索好友、添加删除好友的基本操作单位。
图4-1 注册截图????
???????? ?输入数据注册成功跳转到登录界面:
????????????????????????????????????????????????????????????????????? 图4-2 注册成功截图
登录界面主要是由用户来操作的,所以要简单明了易操作。利用数据库对用户信息进行核对,核对正确后利用界面跳转到QQ主界面。用户的账号密码是提前自己在注册界面注册并保存在服务器数据库中的,每个用户都有自己单独的唯一的一个账号密码用来登录。
图4-3 登录截图
登陆成功之后进入主界面:
????????????????????????????????????????????????????????????????图4-4 主界面
添加好友:
搜索好友:在指定文本框输入想要搜索的qq账号
图4-5 输入qq账号
在输入账号后,会出现找人:1,意思为找qq号有1或者昵称有1的qq用户
图4-6 查找qq用户
???????? 再次输入可以再次筛选指定的qq用户:
添加好友:点击qq用户列表进入qq用户详细信息页面可以添加好友
图4-7 添加好友
点击完添加好友后,出现提示:
图4-8 成功发起好友申请
登录被添加好友的账号,主界面上会有1条好友信息提示:
?????????????????????????
图4-9 好友验证显示
点击新朋友图标,进入所有好友申请列表:
????????????????????????????????????????????????????????????????图4-10 好友申请列表
点开申请人信息,可以选择同意或者拒绝:
图4-11 同意或者拒绝
点击同意,在主界面的好友列表中就有了这个新加的朋友:
图4-12 成功添加好友
点开新的好友头像进入聊天界面并发送消息:
图4-13 聊天界面
聊天消息将会保存在数据库中,等好友上线会收到,好友回复信息时自己也会收到。
等待好友回复信息并再次发送新消息:????????????????
图4-14聊天
回到主页点击动态,会进入好友动态页面。
图4-15 好友动态界面
好友动态功能可以发表附带图片的说说,能查看好友发表的动态,并最新的动态显示在前面。
点击右上角+号准备发布新说说:
图4-16 写说说
输入文字和选择图片:
图4-17 删除说说选中的图片
选择的图片并且能删除,删除后发表:
图4-18 发表的说说
登录另一个账号查看是否有这个好友的动态并且发表最新动态:
图4-19 查看好友说说
图4-20 自己也发了说说图
点击好友头像进入详细信息:
图4-21 好友信息
好友管理能对自己的好友操作,进行分组,分成家人、好友、同学、朋友组,并且能删除好友。?
点击移动分组:
????????????????
图4-22 移动分组
选择要分在家人这组项并点击完成:
图4-22 移动分组成功
再次点击好友头像进入详细信息:
图4-23 进行删除操作
点击删除好友:
图4-24 删除好友成功
4.1.3功能概括和关键代码
1. 添加好友
在android_qq_hy表中,重要的是myqq_id,与hyqq_id,myqq_id是发起添加好友的用户,hyqq_id是被添加好友的用户。假设:小明向小花发送好友请求。
(1)在HyUserZiliaoActivity中小明发送申请,被添加者是小花,直接往数据库好友表里添加一行好友数据,其中myqq_id是小明发起添加好友的人,hyqq_id是小花被添加好友的人,但是状态为0,代表小花未同意。
public void addRen(AndroidQqUser hyuser){
???????? AsyncHttpClient client = new AsyncHttpClient();// 开启网络请求对象类
???????? String uri =URI_IP.URI+"Android_Service/QQ/becomeQqhy";//设置好请求的网络路径
???????? RequestParams params = new RequestParams();// 要请求时附带的参数
???????? // 具体数据信息
???????? params.put("qqhy.myqqId",qquser.getQqId()+"");// 我的id
???????? params.put("qqhy.myqqZhanghao",qquser.getQqZhanghao());
???????? params.put("qqhy.myqqName",qquser.getQqName());
???????? params.put("qqhy.myqqTouxiang",qquser.getQqTouxiang());
???????? params.put("qqhy.myqqMark",qquser.getQqMark());
???????? params.put("qqhy.myqqStatu",qquser.getQqStatu()+"");//在线还是下线
???????? params.put("qqhy.myqqFengzu", 0+"");//默认好友
???????? params.put("qqhy.hyqqId",hyuser.getQqId()+"");// 被添加好友的id
???????? params.put("qqhy.hyqqZhanghao",hyuser.getQqZhanghao());
???????? params.put("qqhy.hyqqName",hyuser.getQqName());
???????? params.put("qqhy.hyqqTouxiang",hyuser.getQqTouxiang());
???????? params.put("qqhy.hyqqMark",hyuser.getQqMark());
???????? params.put("qqhy.hyqqStatu",hyuser.getQqStatu()+"");
???????? params.put("qqhy.hyqqFengzu", 0+"");//默认分组在好友,等下移动
???????? params.put("qqhy.hyStatu",0+"");
????????
???????? client.post(uri,params,new JsonHttpResponseHandler(){
???????????? @Override
???????????? public void onStart() {??????
???????????? }
???????????? @Override
???????????? public void onFailure(Throwable arg0, String arg1) {
???????????????? //登录失败-网络问题
???????????????? handler.sendEmptyMessage(2);
???????????? }
???????????? @Override
???????????? public void onSuccess(int arg0, JSONObject arg1) {
???????????????? //如果Jsonobject获取的值不正确(jsonview)是不会继续下去的
???????????????? int result=arg1.optInt("result");
???????????????? if(result==1){// 当为1 代表在数据库中插入成功
????????????????????? handler.sendEmptyMessage(3);
???????????????? }else{
????????????????????? handler.sendEmptyMessage(4);
???????????????? }
???????????? }
???????????? @Override
???????????? public void onFinish() {
???????????? }
???????? });
??? }
(2)在服务器端,具体操作数据库,往好友表添加一行数据的action
public String becomeQqhy(){//状态为0
???????? try{
???????????? PrintWriter out = response.getWriter();
???????????? boolean bln=ss.addQqhy(qqhy);
???????????? if(bln){
???????????????? result=new ResultFail(1);
???????????? }else{
???????????????? result=new ResultFail(0);
???????????? }
???????????? out.print(JSON.toJSONString(result));
???????????? out.close();
???????? }catch(Exception e){
???????? }
???????? return null;
??? }
(3)小花登录后点击同意好友,则将这行数据的状态改为1,代表同意。
private int hystatu;
??? public String UpdHaoYou(){
???????? System.out.println(hyId);
???????? System.out.println(hystatu);
???????? try{
???????????? PrintWriter out = response.getWriter();
???????????? AndroidQqHy qqhys = ss.getQqhy(hyId);// 先通过主键查到是哪行数据
???????????? qqhys.setHyStatu((long)hystatu);// 查到后设置状态为传入的状态,同意还是拒绝
???????????? boolean bln=ss.updHaoYouStatu(qqhys);// 修改
???????????? System.out.println(bln);
???????????? if(bln){//成功失败
???????????????? result = new ResultFail(1);
???????????? }else{
???????????????? result = new ResultFail(0);
???????????? }
???????????? out.print(JSON.toJSONString(result));
????????????
???????????? out.close();
???????? }catch(Exception e){
???????? }
???????? return null;
??? }
注意:小明与小花的好友关系在数据库只存在一条数据,重要概念是
当小明登录账号时, hyqq_id是小花的id,说明小明的好友有小花。
当小花登录账号时,myqq_id是小明的id,hyqq_id是小花的id,这就要转换成,小花的好友有小明。
2.聊天
在android_qq_message表中,qq_id是发送消息的当前登录账号,m_jsid是被发送消息的好友账号,与好友android_qq_hy表一样,发送者与接受者在不同账号中可以转换。
(1)在ChartActivity中小明对小花发送消息”小花你好”,发送者是小明,也就是在好友表中为myqq_id的人,接受者是小花,也就是在好友表中为hyqq_id的人。聊天界面上显示,右边是小明的头像和 ”小花你好”
?? public void sendMsgTodateOfHy(String str){
???????? sendmsg=new AndroidQqMessage(); // 这个消息对象是为了发送消息后,直接在消息列表中,而不用在数据库中查找出来
???????? //日期
???????? Date date=new Date();//
???????? AsyncHttpClient client = new AsyncHttpClient();// 发送网络请求对象
???????? String uri =URI_IP.URI+"Android_Service/QQ/sendMessage";// 地址
???????? RequestParams params = new RequestParams();// 参数组成
???????? // qqname是当前聊天的对象就是好友的昵称,与qqhy是我与好友在数据库中存储的这一条数据
???????? // 当好友的昵称在qqhy表中是被添加的好友,那么发送者是我,接受者是好友
???????? if(qqname.equals(qqhy.getHyqqName())){
???????????? params.put("msg.qqId", qqhy.getMyqqId()+"");// 设置发送者id
???????????? params.put("msg.qqZhanghao", qqhy.getMyqqZhanghao());// 设置发送者qq账号
???????????? params.put("msg.qqName", qqhy.getMyqqName());// 设置发送者昵称
???????????? params.put("msg.qqTouxiang", qqhy.getMyqqTouxiang());// 设置发送者头像
???????????? params.put("msg.MJsid", qqhy.getHyqqId()+"");// 设置接受者id
???????????? params.put("msg.MZhanghao", qqhy.getHyqqZhanghao());// 设置接受者账号
???????????? params.put("msg.MName", qqhy.getHyqqName());// 设置接受者昵称
???????????? params.put("msg.MTouxiang", qqhy.getHyqqTouxiang());// 设置接受者头像
???????????? sendmsg.setQqId(qqhy.getMyqqId());
???????????? sendmsg.setQqZhanghao(qqhy.getMyqqZhanghao());
???????????? sendmsg.setQqName(qqhy.getMyqqName());
???????????? sendmsg.setQqTouxiang(qqhy.getMyqqTouxiang());
???????????? sendmsg.setMJsid(qqhy.getHyqqId());
???????????? sendmsg.setMZhanghao(qqhy.getHyqqZhanghao());
???????????? sendmsg.setMName(qqhy.getHyqqName());
???????????? sendmsg.setMTouxiang(qqhy.getHyqqTouxiang());
???????? }else{// 当好友的昵称在qqhy表中是发起添加的我,那么发送者是好友,接受者是我
???????????? params.put("msg.qqId", qqhy.getHyqqId()+"");
???????????? params.put("msg.qqZhanghao", qqhy.getHyqqZhanghao());
???????????? params.put("msg.qqName", qqhy.getHyqqName());
???????????? params.put("msg.qqTouxiang", qqhy.getHyqqTouxiang());
???????????? params.put("msg.MJsid", qqhy.getMyqqId()+"");
???????????? params.put("msg.MZhanghao",? qqhy.getMyqqZhanghao());
???????????? params.put("msg.MName", qqhy.getMyqqName());
???????????? params.put("msg.MTouxiang", qqhy.getMyqqTouxiang());
???????????? sendmsg.setQqId(qqhy.getHyqqId());
???????????? sendmsg.setQqZhanghao(qqhy.getHyqqZhanghao());
???????????? sendmsg.setQqName(qqhy.getHyqqName());
???????????? sendmsg.setQqTouxiang(qqhy.getHyqqTouxiang());
???????????? sendmsg.setMJsid(qqhy.getMyqqId());
???????????? sendmsg.setMZhanghao(qqhy.getMyqqZhanghao());
???????????? sendmsg.setMName(qqhy.getMyqqName());
???????????? sendmsg.setMTouxiang(qqhy.getMyqqTouxiang());
???????? }
???????? params.put("msg.MMessage", str);// 设置聊天消息
???????? params.put("msg.MStatu", 0+"");
???????? sendmsg.setMMessage(str);// 设置聊天消息
???????? sendmsg.setMDate(date.getTime());
???????? sendmsg.setMStatu((long)0);
???????? client.post(uri,params,new JsonHttpResponseHandler(){
???????????? @Override
???????????? public void onStart() {??????
???????????? }
???????????? @Override
???????????? public void onFailure(Throwable arg0, String arg1) {
???????????????? //登录失败-网络问题
???????????????? handler.sendEmptyMessage(2);
???????????? }
???????????? @Override
???????????? public void onSuccess(int arg0, JSONObject arg1) {
???????????????? int result=arg1.optInt("result");
???????????????? if(result==1){// 发送是否成功
????????????????????? handler.sendEmptyMessage(1);
???????????????? }else{
????????????????????? handler.sendEmptyMessage(0);
???????????????? }
???????????? }
???????????? @Override
???????????? public void onFinish() {
???????????? }
???????? });
??? }
(2)在服务器端真正的添加一行消息记录进入数据表中
?? public String sendMessage(){
???????? try{
???????????? PrintWriter out = response.getWriter();
?????? ?????? Date dd=new Date();
?????? ?????? msg.setMDate(dd);
???????????? boolean bln = ss.addMsg(msg);
???????????? System.out.println(bln);
???????????? //返回成功等待图片取消 添加到list中
???????????? if(bln){
???????????????? result = new ResultFail(1);//成功
???????????? }else{
???????????????? result = new ResultFail(0);//失败 就弹出失败的哪个图片
???????????? }
???????????? out.print(JSON.toJSONString(result));
????????????
???????????? out.close();
??? ??? }catch(Exception e){
???????????? e.printStackTrace();
???????? }??
???????? return null;
??? }
(3) 当在小花的手机上接受信息时候,查找有关于发送者是小明,接受者是小花或者发送者是小花,接受者是小明的信息行。
//在聊天界面时 获取的消息列表
??? public List getChartList(Long qqId,Long hyId){
???????? return listbysql("select m_id from android_qq_message where (qq_id="+qqId+" and? m_jsid="+hyId+") or (qq_id="+hyId+" and? m_jsid="+qqId+") order by m_date");
??? }
(4) 当在小花的手机上聊天界面中的消息显示,发送者是小明,接受者是小花,但是发送者不是当前登录者小花,于是这条信息”小花你好呀”会被放在左边。
(5)当小花回复信息给小明”小明你好,怎么了”,发送者是小花,接受者是小明,发送者是当前登录者小花,于是这条信息”小明你好,怎么了”会放在右边
(6)在小明手机里,接受到小花发来的信息”小明你好,怎么了”,这时候发送者是小花,接受者是小明,但是发送者不是当前登录者小明,于是这条信息会放在左边
聊天页面的显式代码在ChartBasadpter.java文件
(7)实时获取对方发来的信息是通过Handler来发送延迟信息查询数据库实现的。
handler.sendEmptyMessageDelayed(6, 12000);//一直查询
private Handler handler = new Handler(){
???????? @Override
???????? public void handleMessage(Message msg) {
???????????? int what = msg.what;
???????????? switch (what) {
???????????? case 0://发送消息失败
???????????????? break;
???????????? case 1://发送成功添加到list
???????????????? chartlist.add(sendmsg);
???????????????? //刷新
???????????????? notifylist();
???????????????? //如果是第一条还要显示在消息列表中 和 我是发送者则显示 用广播和全局的msglist 用sendmsg和msglist比较
???????????????? //checkifExit(sendmsg);
???????????????? break;
???????????? case 2://网络
???????????????? Toast.makeText(ChartActivity.this, "网络连接失败", 0).show();
???????????????? break;
???????????? case 3:
???????????????? //显示在聊天列表
???????????????? notifylist();
???????????????? break;
???????????? case 4:
???????????? ??? Toast.makeText(ChartActivity.this, "网络连接失败", 0).show();
???????????????? break;
???????????? case 5://无消息
???????????????? handler.sendEmptyMessageDelayed(6, 12000);//一直查询
???????????????? //new chartlist
???????????????? chartlist = new ArrayList<AndroidQqMessage>();
???????????????? break;
???????????? case 6:
???????????????? getMsgOfdate();
???????????????? break;
???????????? default:
???????????????? break;
???????????? }
???????? }
??? };
- 好友动态功能??????
主要文件DongTaiActivity.java
好友动态功能能查看好友发表的说说,最主要的就是查询自己好友的动态和根据时间来逆序排序,还有上传的图片能查看到。
(1)小明点击动态图标弹出新页面,里面有好友的发的说说。需要在后台查询出说说数据。并且要加上小明自己发的说说。
?? public String dynamic(){
???????? try{
???????????? System.out.println(CurrPage);
???????????? System.out.println(PageCount);
???????????? PrintWriter out = response.getWriter();
???????????? //根据qq_id查询好友 封装为Arraylist
???????????? List hylist = ss.selhy(qqId);//有3个字段,主要获取myqq_id和hyqq_id
???????????? //根据myqq_id或者hyqq_id查找动态 根据qqId筛选好友的
???????????? qqhyidlist = new ArrayList();//QQ好友id列表
???????????? for(int i=0;i<hylist.size();i++){
???????????????? Map hymap = (Map)hylist.get(i);
???????????????? Long hyqq_id = Long.parseLong(hymap.get("hyqq_id")+"");
???????????????? Long myqq_id = Long.parseLong(hymap.get("myqq_id")+"");
???????????????? if(hyqq_id==qqId){//如果自己为好友
????????????????????? System.out.println("进来吧hyqq_id");
????????????????????? qqhyidlist.add(myqq_id);
???????????????? }else if(myqq_id==qqId){
????????????????????? System.out.println("进来吧myqq_id");
????????????????????? qqhyidlist.add(hyqq_id);
???????????????? }
???????????? }
???????????? qqhyidlist.add(qqId);//加上我
???????????? List dynamiclist = ss.seldynamic(qqhyidlist,(CurrPage-1)*PageCount,PageCount);//QQ好友动态 是开始第几个和结束的
???????????? List dynamiclists = new ArrayList<AndroidQqDynamic>(dynamiclist.size());//转换为dynamic对象list
???????????? for(int j=0;j<dynamiclist.size();j++){
???????????????? Map map = (Map)dynamiclist.get(j);
???????????? ??? Long dyId=Long.parseLong(map.get("dy_id")+"");
???????????????? AndroidQqDynamic dy = ss.getdynamic(dyId);
???????????????? dynamiclists.add(dy);
???????????? }
???????????? qqdtlist = new AndroidQqDynamicList(1,dynamiclists);
???????????? out.print(JSON.toJSONString(qqdtlist));
????????????
???????????? out.close();
???????? }catch (Exception e) {
???????? }
????????
???????? return null;
??? }
(2)小明发说说,添加图片和输入文字点击发送后,图片文件将会保存在服务器中,而android_qq_dynamic中的dy_photos字段保存的是图片文件保存在服务器的路径+小明qq号+文件名,多个图片的文件用逗号。发说说文字与图片上传到服务器是分开来的,图片有自己指定的action,表数据也有专门的action去执行。
a.上传文件到服务器指定位置
安卓端代码:??
public void sendPhotos(){
???????? for(int i=0;i<file.length;i++){// 选择的图片文件数组
???????????? if(file[i]!=null){
???????????????? AsyncHttpClient client = new AsyncHttpClient();// 网络请求
???????????????? String uri=URI_IP.URI+"Android_Service/QQ/saveDtPhotos";// 地址
???????????????? RequestParams params = new RequestParams();// 组成参数
???????????????? try {
????????????????????? params.put("file", file[i]);// 图片文件可以直接传入
???????????????? } catch (Exception e) {
????????????????????? // TODO 自动生成的 catch 块
????????????????????? e.printStackTrace();
???????????????? }
???????????? ??? params.put("dynamicnamephoto",dynamicnamephoto[i]);//dynamicnamephoto是选择的图片名称
???????????????? client.post(uri,params,new JsonHttpResponseHandler(){
????????????????????? @Override
????????????????????? public void onStart() {??????
????????????????????? }
????????????????????? @Override
????????????????????? public void onFailure(Throwable arg0, String arg1) {
????????????????????????? //登录失败-网络问题
????????????????????????? handler.sendEmptyMessage(2);
????????????????????? }
????????????????????? @Override
????????????????????? public void onSuccess(int arg0, JSONObject arg1) {
????????????????????????? //如果Jsonobject获取的值不正确(jsonview)是不会继续下去的
????????????????????????? int result=arg1.optInt("result");
????????????????????????? if(result==1){
????????????????????????????? handler.sendEmptyMessage(3);
????????????????????????? }else{
????????????????????????????? handler.sendEmptyMessage(4);
????????????????????????? }
????????????????????? }
????????????????????? @Override
????????????????????? public void onFinish() {
????????????????????? }
???????????????? });
???????????? }else{
???????????????? i=file.length;
???????????? }
???????? }
???????? handler.sendEmptyMessage(3);
??? }
服务器代码:
public String saveDtPhotos(){
???????? try {
???????????? PrintWriter out = response.getWriter();
???????????? System.out.println(file[0].getName());
???????????? // 使用文件输出流输出图片
???????????? FileOutputStream fos=new FileOutputStream(this.savePath+dynamicnamephoto[0]);
???????????? // 先将上传的文件转换为文件输入流
???????????? FileInputStream fil=new FileInputStream(this.file[0]);
???????????? // 每次读入 写出的大小。
???????????? // io流,就是先从文件输入流中读入1024字节,再用文件输出流输出1024字节到(this.savePath+dynamicnamephoto[0])这个文件夹里
???????????? byte[] b=new byte[1024];
???????????? int real=fil.read(b);
???????????? int ii=0;
???????????? while(real>0){
???????????????? fos.write(b, 0, real);
????????????????
???????????? ??? real=fil.read(b);//每次读入 写出 文件对象就会少去这部分,所以这样1kb1kb写出 知道 读入不了了
????????????????
???????????????? ii++;
???????????? }
???????????? System.out.println(ii);
???????????? fos.close();fil.close();
???????????? result = new ResultFail(1);
???????????? out.print(JSON.toJSONString(result));
???????? } catch (Exception e) {
???????????? // TODO Auto-generated catch block
???????????? e.printStackTrace();
???????? }
???????? return null;
??? }
b.上传说说一行表数据到action保存
安卓端代码:??
public void add(){
???????? Date date = new Date();
???????? AsyncHttpClient client = new AsyncHttpClient();
???????? String uri=URI_IP.URI+"Android_Service/QQ/adddynamic";
???????? RequestParams params = new RequestParams();
???????? params.put("qqdynamic.qqId", qquser.getQqId()+"");
???????? params.put("qqdynamic.qqZhanghao", qquser.getQqZhanghao());
???????? params.put("qqdynamic.qqName", qquser.getQqName());
???????? params.put("qqdynamic.qqTouxiang", qquser.getQqTouxiang());
???????? params.put("qqdynamic.dyDate",date.toLocaleString());
???????? params.put("qqdynamic.dyContent",adddt_rl2_et1.getText().toString());
???????? for(int i=0;i<dynamicnamephoto.length;i++){
???????????? Object obj = dynamicnamephoto[i];
???????????? if(obj!=null){
???????????????? dyPhotos+=dynamicnamephoto[i]+",";//数据库字符串
???????????? }else{
???????????????? i=dynamicnamephoto.length;
???????????? }
???????? }
???????? params.put("qqdynamic.dyPhotos", dyPhotos+"");//多张图片用,号隔开 取也是。。。 这个文件名需要重新定义在组成这个
???????? client.post(uri,params,new JsonHttpResponseHandler(){
???????????? @Override
???????????? public void onStart() {??????
???????????? }
???????????? @Override
???????????? public void onFailure(Throwable arg0, String arg1) {
???????????????? //登录失败-网络问题
???????????????? handler.sendEmptyMessage(2);
???????????? }
???????????? @Override
???????????? public void onSuccess(int arg0, JSONObject arg1) {
???????????????? //如果Jsonobject获取的值不正确(jsonview)是不会继续下去的
???????????????? int result=arg1.optInt("result");
???????????????? if(result==1){
????????????????????? handler.sendEmptyMessage(1);
???????????????? }else{
????????????????????? handler.sendEmptyMessage(0);
???????????????? }
???????????? }
???????????? @Override
???????????? public void onFinish() {
???????????? }
???????? });
??? }
服务端代码:??
//上传的文件名称
??? private String[] dynamicnamephoto;
??? public String adddynamic(){
???????? //返回json
???????? try {
???????????? PrintWriter out = response.getWriter();
???????????? boolean bln= ss.addQqDt(qqdynamic);
???????????? System.out.println(bln);?????
???????????? //上传成功并重新获取刷新页面
???????????? if(bln){
???????????????? result = new ResultFail(1);
???????????? }else{
???????????????? result = new ResultFail(0);
???????????? }
???????????? out.print(JSON.toJSONString(result));
???????????? out.close();
???????? } catch (IOException e) {
???????????? // TODO 自动生成的 catch 块
???????????? e.printStackTrace();
???????? }
???????? return null;
??? }
4.2服务器端的实现概括
- 服务器端功能
主控计算机处理各无线终端发送过来的数据信息并进行处理、加工(必要的情况下还进行信息回馈)以及发送,从而进行一系列功能操作。
服务端主要是数据库操作,针对无线终端各模块而设置响应相应功能的服务器小程序。主要的Servlet(如图显示)。
图4-17 服务器功能图
2. 服务器端代码例子
action
//1.注册用户
??? public String zhuce(){
???????? try{
???????????? // 获取移动端传来的数据
???????????? PrintWriter out = response.getWriter();
???????????? System.out.println("进来了注册");
???????????? System.out.println(qquser.getQqAddress()+qquser.getQqZhanghao());
???????????? // 添加到数据库中
???????????? boolean bln=ss.addUser(qquser);
???????????? // 返回是否添加成功
???????????? if(bln){
???????????????? result=new ResultFail(1);
???????????? }else{
???????????????? result=new ResultFail(0);
???????????? }
???????????? out.print(JSON.toJSONString(result));// 返回json格式数据
????????????
???????????? out.close();
???????? }catch (Exception e) {
???????? }
???????? return null;
??? }
五、结? 论
通过开发系统,我较全面的掌握了JAVA-Android开发的基本知识和编程技巧,并在开发过程中我的开发能力得到了进一步的提高。如:更进一步的深入了解Android开发、SQL语言的使用、解决Bug能力。
在开发过程中我学到了一些经验:系统分析的好坏将决定着的系统开发成功与否,一份好分析设计将是成功开发主要因素。我们在着手开发之前不要急于编程,先应有较长的时间去把分析做好,做好数据库设计工作,写出相关的开发文档等。然后再开始编写程序代码,这样做到每写一步代码心底有数,有条不絮。
此外,我还觉得,我个人在这次设计中走了很多弯路。主要是因为平时很少接触软件开发工作,在应用方面缺乏经验,以后还需要更多的努力。
对我来说,这次设计的本身所产生的影响,还远远没有结束,我从本次毕业设计中学到了许多课本上没有的知识。通过自己的学习和努力;通过老师的指导和教育,使我不仅仅在知识水平和解决实际问题的能力上有了很大的提高。还从思想的深处体会到,要把自己的所学变成现实时所将面对的种种难题。
|