IM即时通讯H信 Android

793 阅读10分钟

一、概述

 1、开发环境及安装配置

开发环境Windows10下基于JRE1.8.0、OpenJDK Server VM的集成开发工具Android Studio 3.5和环信即时通讯云Android SDK。安装配置需要在环信创建应用,获得AppKey并在项目中导入easeui模块。即时通信简称 IM,它是一种基于互联网的即时交流消息的业务,允许两人或多人使用网络即时的进行文字的交互、音频的交互、视频的交互等。该系统高效、稳定、安全,同时很多即时通信系统还支持点对点的数据交换等功能。常见的即时通讯工具微信被人们常称V信,所以我开发的即时通讯取名H信,H代表开发者姓名首字母,信代表即时通信。

2、项目的需求分析

如今人人离不开手机,据调查大多数人在使用手机的大部分时间都在使用网络通讯。即时通讯改变了人们的沟通方式,即使相离的很远,也可以随时联系对方。现有的即使通讯软件已经十分成熟,例如:QQ、微信等,这类通讯软件带有娱乐成分的功能,可能会对工作和学习带来一定的影响。就现状开发一款只涵盖即使通讯的软件H信,供用人单位或学校,达到既不耽误沟通又不影响做正事的目的。即时通信系统客户端软件与其他商业软件需求有很大的不同,因此本课题研发的软件主要面向特殊的应用场景,软件的设计和实现过程需要遵循以下几项原则:朴实的界面设计,界面设计需要遵循以下原则:界面简洁,在软件设计和实现的过程中,所有弹出的窗口不能超过一层,不能有层层堆叠的现象,不能无故为操作增加复杂度;用户注册、用户登录、添加联系人、聊天窗口的开启等所有操作务必要简单、快捷,限制在两次点击以内;方便易用,考虑到面向的群体很大,就要保证设计的按键足够的大,确保中老年人也可以准确的点击。功能设计简单:需要实现基本的通信功能,不需要附加其余复杂、繁琐的功能。同时必须为其他软件的运行节省出宽带资源,不能占用多余带宽。支持跨平台的应用。本课题研究的即时通信软件客户端主要是为了在 Android 系统上运行,但是为了确保可以兼容其它设备,所以在软件设计和实现的过程中需要考虑将其应用于包括Windows10、MacOS以及 iOS等其它操作系统上。

二、程序概要设计

3、程序的功能模块

进入程序前3秒欢迎页面、登录和注册功能、添加好友、与好友会话、创建群组会话、语音对话、发送标签文字、发送图片、发送定位、文件传输、修改个人信息。即时通信客户端软件功能完备,操作简单,用户短时间内便可以掌握软件的操作方法。具体包括 :用户的身份验证,注册新用户,登录系统,好友添加,图片的发送,文字的发送以及文件的传输功能和最终用户退出系统等功能。用户登录即时通信客户端程序之后,面对的便是为新用户和已有用户准备的注册与登录的界面。这一界面用户可以根据自己的身份选择进行哪一项操作。共有两项选择供用户选择:如果用户之前已经注册了有效的账号,那么该用户就可以按照界面提供信息进行身份的验证,然后顺利登录。如果用户是第一次作为新人登录该界面,那么新用户可以填写相关信息进行新账号的注册。用户在登录系统之后,如果想和某位用户通信,那么用户可以先对该用户进行搜索,然后将其添加到自己的联系人列表中。先要把这个账号添加到自己的联系人列表中。联系人列表可按照以下两种方式进行排列:通常排在前面的是在线的联系人,排在后面的表示该用户已经离线了。当多个用户同时在线时,列表中会按照账号的字母顺序对用户进行排列。如果用户想跟列表中的某位在线的联系人进行通信,可以点开对话窗口,给对方发送信息,与对方进行通信对话。对话窗口界面主要分为三个部分,它们分别是信息输入区、消息提示区以及视频播放区。一般地,对话窗口的左上部分为消息提示区,主要负责将联系人的消息进行分行显示。消息内容可以是文字内容,也可以图片的传送、文件的传输,或是音频、视频的展示等。而且不同形式的信息表现的形式也是多种多样的。具体如下:消息区直接显示文字或是图片内容;对于音频、视频信息,消息区一般会显示出提示的符号,在线者只要将其点开就可阅读;对于他人所传送的文件,消息区会显示出链接的方式,在线者打开即可;地图输入:对于这部分内容本文不作详细论述,原因在于它是与地理信息系统的交互功能;一般地,对话窗口的底部是信息输入区,信息输入区主要负责将用户自身需要传送的文字内容、图片、文件、视频等信息发送给其他用户。信息的传送方式具体如下:文字输入:点击“文字”,然后在信息输入区内直接敲击文字,便可直接将其输入;音/视频输入:点击“视频”,便会有一个对话框弹出供用户浏览,选择个人需要的音频或是视频文件将其传送即可;图片输入:点击“图片”,同样会有一个对话框弹出供用户浏览,选择个人需要的图片文件直接插入即可;点击“文件”,相应地对话框便会弹出,选择个人需要的文件夹进行传送即可;地图输入 :对于这部分内容本文不作详细论述,原因在于它是与地理信息系统的交互功能;消息窗口的右上部分为视频区,在这一区域内可显示一个视频或是多个视频,用户可对某一视频对象窗口进行单独关闭或是禁音操作。就地理信息系统而言,即时通信客户端软件需要配合它完成以下几项功能:即时通信客户端软件可将指挥中心最新动态及时的通知用户,如果有更准确、更详细、分辨率更高的地图发布时,该软件可以提醒用户在合适的时候去获取新更新的地图。此外,即时通信客户端软件可以将任何其他终端发布的地理相关信息传达给用户。

4、程序的流程

5 、程序的文件结构分析



H信是按MVC模式设计的:

模型层:主要处理数据

控制层:处理业务逻辑

显示层:显示数据

com.example.im.controller                               控制层

com.example.im.controller.activity                  应用界面活动

com.example.im.controller.fragment              存放fragment替换activity实现界面

com.example.im.controller.adapter                显示列表的适配器

com.example.im.model                                     数据模型层

com.example.im.model.bean                           数据对象封装

com.example.im.model.dao                             数据库操作类

com.example.im.model.db                               数据库

com.example.im.runtimepermissions            线程池

com.example.im.utils                                        相关工具类

6、数据库的设计

用户账号表:表名为tab_account。

属性:姓名name、环信id为主键hxid、昵称nick、头像photo。

public class UserAccountTable {

 public static final String TAB_NAME = "tab_account";

 public static final String COL_NAME = "name";

 public static final String COL_HXID = "hxid";

 public static final String COL_NICK = "nick";

 public static final String COL_PHOTO = "photo";

 public static final String CREATE_TAB = "create table "

 + TAB_NAME + " ("

 + COL_HXID + " text primary key, "

 + COL_NAME + " text,"

 + COL_NICK + " text,"

 + COL_PHOTO + " text);";

}

联系人表:表名为tab_contact。

属性:姓名name、环信id为主键hxid、昵称nick、头像photo、是否为好友is_contact。

public class ContactTable {

    public static final String TAB_NAME = "tab_contact";

    public static final String COL_HXID = "hxid";

    public static final String COL_NAME = "name";

    public static final String COL_NICK = "nick";

    public static final String COL_PHOTO = "photo";

    public static final String COL_IS_CONTACT = "is_contact";

    public static final String CREATE_TAB = "create table "

            + TAB_NAME + " ("

            + COL_HXID + " text primary key,"

            + COL_NAME + " text,"

            + COL_NICK + " text,"

            + COL_PHOTO + " text,"

            + COL_IS_CONTACT + " integer);";

}

请求信息表:表名为tab_invite。

属性:用户名称user_name、用户环信id为主键user_hxid、群组名group_name、群组id为group_hxid、请求原因reason、请求状态status。

public class InviteTable {

    public static final String TAB_NAME = "tab_invite";

    public static final String COL_USER_NAME = "user_name";

    public static final String COL_USER_HXID = "user_hxid";

    public static final String COL_GROUP_NAME = "group_name";

    public static final String COL_GROUP_HXID = "group_hxid";

    public static final String COL_REASON = "reason";

    public static final String COL_STATUS = "status";

    public static final String CREATE_TAB = "create table "

            + TAB_NAME + "("

            + COL_USER_HXID + " text primary key, "

            + COL_USER_NAME + " text, "

            + COL_GROUP_NAME + " text, "

            + COL_GROUP_HXID + " text, "

            + COL_REASON + " text, "

            + COL_STATUS + " integer);";

}

三、程序详细设计

7、关键代码分析

配置 AndroidManifest.xml 清单文件,通过标签配置所需要获取到的权限。如:读写权限、网络权限、相机权限。还需设置环信应用的AppKey通过和声明SDK所需的Service通过。

申请权限:

<uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

 

 

 

 

 

 

 

 

 

 

 

 

 

 uses-permissionandroid:name="com.coloros.mcs.permission.RECIEVE_MCS_MESSAGE"/

 

创建 IMApplication,对easeui初始化EaseUI.getInstance().init(this,options);并初始化模型层数据Modle.getInstance().init(this);。

用户打开App首先进入欢迎页面,延迟3秒钟,Handler消息处理。判断是否已经登录EMClient.getInstance().isLoggedInBefore(),如未登录则跳转到登录页面,如已经登录则获取当前用户信息Model.getInstace().getUserAccountDao().getAccountByHxId()、调用登录成功方法创建数据库的管理类、跳转到主页面。

EMClient 环信程序入口:SDK 入口类EMClient.getInstance().init(context,options);注册EMClient.getInstance().createAccount(name,pwd);登录EMClient.getInstance().login(name,pwd);。

登录注册页面实现关键代码,初始化监听(注册/登录),注册流程:获取用户名和密码、开启访问网络线程、去环信创建用户账户EMClient.getInstance().createAccount、将账号信息保存到本地数据库Model.getInstace().getUserAccountDao().addAccount。登录流程:去环信服务器创建登录EMClient.getInstance().login、成功后,调用Model.getInstace().loginSuccess()、保存数据库到本地Model.getInstace().getUserAccountDao().addAccount。

EMChatManager 聊天管理类: EMChatManager chatMgr = EMClient.getInstance().chatManager();主要功能:消息收发、会话管理。

EMContactManager 聊天好友管理类: EMContactManager contactMgr = EMClient.getInstance().contactManager();主要功能:加减好友、黑名单管理。

EMGroupManager 群组管理类:EMGroupManager groupMgr = EMClient.getInstance().groupManager();主要功能:加减群、创建群、私有群、公开群管理。

主界面布局由嵌套和组件构成。加载所有群信息;加载所有会话信息、初始化view(FrameLayout/RadioGroup)、初始化数据;会话fragment、联系人fragment、设置fragment、初始化监听rg_main.setOnCheckedChangeListener()判断选中的item是否和上一次选中的item相同,更新当前选中item标记,根据选中的item赋值相应的fragment,切换对应的fragment getSupportFragmentManager()。每次打开主页面默认加载会话页面rg_main.check(mCheckedId);

设置界面关键代码:加载布局文件、获取退出button按钮对象、获取当前登录用户名称EMClient.getInstance().getCurrentUser()、监听button的点击事件访问网络执行退出登录下线EMClient.getInstance().logout并关闭本地数据库Model.getInstace().getDbManager().close()、提示退出成功,跳转到登录页面并结束当前页面。

联系人界面关键代码:ContactListFragment继承EaseContactListFragment。初始化界面:加载联系人头布局listView.addHeaderView()、头布局加号设置TitleBar.setRightImageResource、获取邀请信息条目的对象、获取群组条目的对象、设置联系人条目的点击事件传递环信id参数mHxid =easeUser.getUsername( );启动跳转到会话详情页面ChatActivity、设置群组条目的点击事件启动跳转到群列表页面GroupListActivity、长按联系人删除联网,从环信服务器删除该联系人EMClient.getInstance().contact Manager().deleteContact(mHxid);从本地数据删除该联系人和邀请信息。注册广播联系人邀请和群邀请信息变化的广播更新UI界面显示红点。

添加好友界面关键代码:获取输入的名称,校验输入的名称不能为空,创建查询的人数据显示和名称显示、监听添加按钮去服务器添加好友EMClient.getInstance().contactManager().addContact(userInfo.getName( ), "添加好友"),全局监听联系人变化。

邀请信息界面关键代码:创建适配器new InviteAdapter(this, mOnInviteListener)、注册联系人邀请信息变化的广播注册群邀请信息变化的广播、接受拒绝按钮回调方法通知环信服务器并更新本地数据库。

会话详情页面关键代码:创建会话的fragment EaseChatFragment( )并注册本地广播的管理者、判断会话类型是否为群、会话页面的监听easeChatFragment.setChatFragmentListener()。

群列表页面关键代码:添加头布局文件Lv_group_list.addHeaderView()、构造适配器GroupListAdapter(Context context)、刷新方法void refresh(List eMGroups)、刷新适配器显示mGroupListAdapter.refresh(EMClient.getInstance().groupManager().getAllGroups());联网获取群信息EMClient.getInstance().groupManager().getJoinedGroupsFromServer();、新建群组条目点击事件跳转新建群页面、群列表的点击事件获取群id EMClient.getInstance().groupManager().getAllGroups().get(position - 1) .getGroupId();并从环信服务器获取群组联系人信息。

新建群页面关键代码:带回调方式启动选择联系人页面、去环信服务器建群EMClient.getInstance().groupManager().createGroup(groupName,groupDesc, memberses,reason, options);

群联系人选择页面关键代码:获取传递过来的群id根据群id获取群成员信息、从本地数据库获取所有联系人信息将联系人信息转换为选择联系人bean数据创建适配器添加适配器到listview中、获取当前item的checkbox对象从适配器中获取被选择的联系人设置选择的联系人返回到创建群页面。

群详情关键代码:获取群id getIntent().getExtras().getString(Constant.GROUP_ID);再用群id获取群信息EMClient.getInstance().groupManager().getGroup(groupId);如果为群主则有解散群、如果是群成员则退群、解散群和退群广播broadCastExitGroup()、布局中GridView 触摸事件、适配器回调接口。添加群成员EMClient.getInstance().groupManager().addUsersToGroup

(group.getGroupId(), memberses);。

8、疑难问题解决

将环信SDK的easyui导入项目初始化easyui后编译发生错误,查询了很多资料在这里卡了很久。最后发现是easyui 中的 v4 包和主项目中的 v7 包冲突。解决办法在项目的 build.gradle 将 v7 包中的 v4 包移除。环信IM开发文档Android客户端集成写的比较难看懂只能通过不断地搜索资料爬楼逐一解决问题。

关于修改个人资料环信官方只给出昵称一个属性,而且只能设置昵称无法获取昵称。这不利于修改资料的功能展示,用户不能得知是否修改成功。解决办法:创建一个本地数据库保存用户的信息,从环信服务器修改个人资料成功时也修改本地数据库,修改成功则从本地数据库查询展示在界面上。

四、程序的发布和测试

9、程序发布过程

通过Android Studio3.5生成APK。点击Build->Generate Signed Bundle / APK。选择APK点击Next。

      ​                

然后创建密钥文件点击Create new填写相关信息点击Next,选的release版本勾选V1、V2。只勾选v1签名并不会影响什么,但是在7.0上不会使用更安全的验证方式、只勾选V2签名7.0以下会直接安装完显示未安装,7.0以上则使用了V2的方式验证、同时勾选V1和V2则所有机型都没问题。点击Finish生成可发布的APK安装包。

       ​      

10、测试过程

H信的测试在虚拟机和真机都进行了测试,暂未发现有BUG。

测试过程:

         使用测试真机进行APP的安装与卸载;功能测试:功能逻辑测试、功能点测试、关联性测试;稳定性测试:交互性测试、异常性测试(手机断电、断网情况);适配性测试:找了几个同学分别是不同的分辨率、系统版本、厂商;网络测试:使用WIFI和手机网络测试APP。界面:文字错误、图片不显示或显示不正确、缺少输入项、按钮的大小和点击效果、布局、图片和配色设计问题,测试人员很难进入、提示信息,提示信息语言准确简洁,有指导性。在应该提示的位置放入提示信息,比如程序需要接入网络,在无网络的情况下应给予提示、提示信息,提示信息的方式有很多,大概有弹出式和非弹出式两种,根据实际情况来区分、阅读性,手机因输入方式和屏幕大小限时。文字字体、大小、颜色和背景颜色可调整,夜间模式、简洁,如穿着白纱美女的油画一般、输入法,输入法不能挡住输入框;回车可以跳转到下一个输入框。稳定性:网络,需要访问网络的程序,在网络不稳定的情况下,应能正常运行,不应出现意外退出和错误;如程序无法在该环境下运行,应提示用户、网络切换、网络信号弱、进程切换,在多进程切换中,应正常运行,并保持切换前页面,不应出现意外退出和错误。性能:程序进行某些功能时,不应使手机出现卡、顿等情况,视实际情况而定。安装:路径,可选择手机、SD卡、覆盖,可覆盖旧版本,并不会出现异常、卸载。升级:提示,在每次程序运行的时候提示,或可以设置不提示新版本、下载,或可设置在特定的网络环境中才允许下载,取消,下载可取消(并可暂停和继续)。操作:查询按钮和回车同时响应搜索、按钮点击有变化。业务:准备,熟悉项目环境背景,了解需求、以业务流程为准,从流程开始到流程结束,至少要包含重要的功能点、不同的流程起点,可以在多个流程用例中体现、不能完全包含所有起点,则单独看。

         主要运用单元测试,集中对每一个程序单元进行测试,检查各个程序模块是否正确地实现了预定的功能,测试范围为单元内部的源代码和程序结构、集成测试把已测试过的模块组装起来,检查模块间接口是否正确,检查各个模块之间的通信和相互调用是否符合需求,测试范围为模块接口之间的数据传递,以及模块组合后的功能。系统测试把被测软件系统和计算机硬件、数据库、外设、前端和后端以及其它软件结合在一起,在实际运行环境下对软件系统进行一系列的组装测试和运行测试,只关心输入和输出结果,测试范围为整个系统。回归测试:是软件发布后的维护阶段或者是研发修复Bug之后进行确认测试。集成测试开始于在完成几个模块的测试之后。一起组合各个模块,然后测试它们是否能够正常的运行。集成测试位于单元测试和系统测试之间,起桥梁纽带作用就是集成测试。随着迭代的次数增加,软件逐渐稳定成熟之后,系统测试即为下一步。由我独立执行系统测试。

产品演示:

第一次打开程序进入欢迎界面3秒后进入登陆注册界面:

           ​        

输入用户名、密码成功注册方可登陆,登陆默认进入会话页面fragment,由于模拟器是安卓9.0所以需要动态获取权限:

           ​      

添加好友:左图,左手边模拟器登录hph账户、右手边登录aaa账户。aaa请求添加hph,hph收到提示小红点。中图:hph同意添加aaa为好友。右图:双方联系人列表互为好友。

  ​     ​    

成为好友以后双发可以通过文字、表情、语音、发送图片、发送定位、文件传输进行即时沟通。对好友长按也可删除好友。

  ​     ​    

创建群组:填写完相关信息点击创建,从好友列表中拉人群,当其他用户同意进群以后群详情将显示群所有成员。

      ​      ​     

群组内聊天有这个个人聊天一样的功能。

修改个人资料,在设置页面点击修改资料,成功修改后返回设置。

              ​      

五、总结

11、优点

App开发的相对比较完整,达到了Android的即时通讯软件客户端的设计与开发的要求。UI界面干净整洁。程序运行比较流畅,程序代码层次清晰,归类合理。模块化很明显,各个模块很明确需要实现的功能,代码也易读,并且做了很多的注释,这也是我往常完成课后作业从没有这种习惯,但课程设计的代码太多,让我体会到了注释的好处。各功能相互调用的比较好。

12、不足

调用第三方环信的SDK,时间原因没有过多的去了解底层的知识。开发即时通讯软件还需要更多的去学习TCP、UDP协议和Socket。对于一个可以上架到应用市场的即时通讯软件,现在的完成度远远不足,更全面需要考虑安全等问题。

13、总结

在做Android应用开发项目实践前,拿到题目是很难选择。自己本身并不打算通过学习Android更扎实自己的Java编程能力。对于开一个论坛目前大多数都是Hybrid App(混合App)用原生安卓进行开发的话逻辑强难度大。对于一个管理系统因为之前没有用过这类的App所以不清楚该如何开始。最后权衡之下选择了即时通讯,也算是完成了大一自己想开发的App其中一个功能。但在开发过程中还是遇到了种种难题是我在课堂中没有接触到的。印证了一句话活到老学到老,更多的是自己在课余时间学习。从一开始无从下手到最后完成一个令自己比较满意的程序,有一种成就感。相信也为我巩固Java编程知识有帮助,提高我的学习兴趣,一路做下来收获了很多课堂中学习不到的知识。任何一门语言光靠理论知识是远远不够的,只有自己动手实践,并理论结合实际才能达到很好的学习效果。

六、参考

  1. 环信IM开发文档Android客户端集成
  2. 第一行代码Android 第2版 郭霖 著 人民邮电出版社
  3. CSDN-专业IT技术社区

源码在github哦GitHub - Hph1998/IM: 基于环信SDK的Android即时通讯H信