仿qq聊天及定位等

聊天其实就是要实现消息推送,而推送消息就需要保持连接(长连接)。在之前项目里虽然实现了即时聊天,但是一种很本的方法。

去掉了其中的网络访问。地图试用的百度API

还是先放上图,在说下做法。

具体做法就是,开启一个服务,在后台每隔10秒钟访问一起(Socket)服务器,如果有数据,则返回数据,客户端进行解析,然后发送广播,即可接收到消息。

发送消息,则是由服务器提供接口来发送。然后,服务器与客户端建立一个简单的通信协议。

如:MSG|发送人ID|2012-2-12 07:25:12|发送类型      MSG是个标识,类型包括文本(包含表情),图片,语音,位置等。

图片和语音的发送,都是通过FTP先上传文件到服务器,然后把本地存储的路径发送给对方。

在聊天的页面中,用户的头像都是在本地存的。包括聊天的信息,也是本地数据库存的。这样就能记录信息。也可以扩展把聊天记录导出。

在本地创建的 消息数据库中。要定义好聊天信心的字段,包括自己ID,好友ID,消息类型,文本内容,时间,是否已读等(可扩展)

01 02 03 04 05 06 07 08 09

private String table = "CREATE TABLE IF NOT EXISTS message(" +                         "_id integer PRIMARY KEY," +                         "TtmType integer ," +                         "TtmTuID integer ," +                         "TtmToUserId integer ," +                         "TtmContent text ," +                         "TtmTime varchar(200) ," +                         "isRead integer ," +                         "isReplyLocation integer )";

这样再次进入聊天页面就可以把数据库的内容读出来,匹配到适配器

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20

public List<DetailEntity> getdatas(int TtmTuID, int TtmToUserId) {                 List<DetailEntity> de = new ArrayList<DetailEntity>();                 SQLiteDatabase database = dbmanger.getWritableDatabase();                   Cursor cursor = database                                 .rawQuery(                                                 "select * from message where (TtmTuID = ? and TtmToUserId = ?) or (TtmToUserId = ? and TtmTuID = ?)  order by _id",                                                 new String[] { String.valueOf(TtmTuID),                                                                 String.valueOf(TtmToUserId),                                                                 String.valueOf(TtmTuID),                                                                 String.valueOf(TtmToUserId)});                 while (cursor.moveToNext()) {                         de.add(new DetailEntity(cursor.getInt(1), cursor.getInt(2), cursor                                         .getInt(3), cursor.getString(4), cursor.getString(5),cursor.getInt(6),cursor.getInt(7)));                   }                 cursor.close();                 database.close();                 return de;         }

图片的查看和语音的播放,都需要从数据库里取出文件保存的路径,不然的会显示和播放都不正确。

仔细看源码的话发现,在进入页面适配数据的时候已经从数据库读取内容了,而在适配器中查看图片,又重新读取了一次,

主要是因为,不这样做还是不能正确显示和播放。  对这个问题很费解。

进入到聊天页面,换取到数据,很据数据类型来加载对应的layout,当然还要判断用户ID,信息的读取是根据用户ID来获取的

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

messageList = MessageSQLService.getInstance(this).getdatas(                                 Integer.valueOf(UserInfomation.getUserID(TalkMessageAct.this)),                                 Integer.valueOf(TFuid)); for (int i = 0; i < messageList.size(); i++) {                   switch (messageList.get(i).getTtmType()) {         case 1:                   int id = Integer.valueOf(messageList.get(i).getTtmTuID());                 if (id == Integer.valueOf(TFuid)) {                   } else if (id == Integer.valueOf(UserInfomation                                 .getUserID(TalkMessageAct.this))) {                                           }                   break;         case 2:                 int ids = Integer.valueOf(messageList.get(i).getTtmTuID());                 if (ids == Integer.valueOf(TFuid)) {                   } else if (ids == Integer.valueOf(UserInfomation                                 .getUserID(TalkMessageAct.this))) {                 }                 break;         case 3:                 int idsx = Integer.valueOf(messageList.get(i).getTtmTuID());                 if (idsx == Integer.valueOf(TFuid)) {                   } else if (idsx == Integer.valueOf(UserInfomation                                 .getUserID(TalkMessageAct.this))) {                 }                 break;         case 5:                 break;         case 6:                 int idsxx = Integer.valueOf(messageList.get(i).getTtmTuID());                 if (idsxx == Integer.valueOf(TFuid)) {                   } else if (idsxx == Integer.valueOf(UserInfomation                                 .getUserID(TalkMessageAct.this))) {                 }                 break;           } }

之前在测试中,用socket实现不了长连接。主要是因为不加上 socket.shutdownOutput();就收不到消息,而加上了即接收完消息断了连接。所以每隔10秒就要访问次Socket服务器

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18

socket = new Socket(Constants.SOCKET_IP, Constants.SOCKET_PORT);           if (socket.isConnected()) {                                   out = new PrintWriter(new BufferedWriter(                                 new OutputStreamWriter(socket.getOutputStream())), true);                 out.write("Lgn|"+                         UserInfomation.getUserID(TalkMessageServer.this)+"|"+                         UserInfomation.getUserPW(TalkMessageServer.this));                 out.flush();                 socket.shutdownOutput();         }         reader = new BufferedReader(new InputStreamReader(                         socket.getInputStream()));         while ((line = reader.readLine()) != null) {                 if (line != null) {                         //截取字符,读取信息的操作                 }

虽然实现了,但在实际的应用中,效果不好。费电,丢包。

当然了,现在正在往长连接方向该,也修改了通信协议(很规范),(SocketChannel,Selector)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯Bugly的专栏

如何定位Obj-C野指针随机Crash(三):如何让Crash自报家门

本文主要介绍如何利用OC Runtime的特性,让OC野指针对象主动抛出自己的信息,秒杀某些全系统栈Crash。 ? 陈其锋,腾讯SNG即通产品部音视频技术中心...

95840
来自专栏tkokof 的技术,小趣及杂念

Coroutine,你究竟干了什么?(小续)

前篇中讲了一些自己关于Coroutine的理解,后来陆陆续续的又想到了一些,在此简单记录一下,内容不多,故作“小”续吧 :)

9020
来自专栏java思维导图

Getter & Setter:使用还是废弃

私有变量 为什么我们要使用私有的实例变量呢? 因为我们不希望其他类直接的依赖于这些变量。而且在心血来潮时,我们还可以灵活的修改变量类型和实现。 然而,为什么程序...

30060
来自专栏我是攻城师

玩转大数据系列之Apache Pig高级技能之函数编程(六)

35430
来自专栏NetCore

[原创]Fluent NHibernate之旅(三)-- 继承

经过了“开篇”和“简单映射”两篇文章,相信大家对Fluent NHibernate 有了一定的了解了,FluentNHibernate实际就是对 NHibern...

20580
来自专栏偏前端工程师的驿站

JS魔法堂:不完全国际化&本地化手册 之 实战篇

前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求——国际化&本地化。熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"...

298100
来自专栏CDA数据分析师

教你一招:用 50 行 Python 代码制作一个计算器

简介 在这篇文章中,我将向大家演示怎样向一个通用计算器一样解析并计算一个四则运算表达式。当我们结束的时候,我们将得到一个可以处理诸如 1+2*-(-3+2)/5...

22870
来自专栏CSDN技术头条

C#秒杀Java的五个不可替代的特性,完美的编程语言并不存在

如果我们可以同时拥有 C# 和 Java 世界的最好特性,那会是什么样呢? 完美的编程语言并不存在,我希望我们可以在这一点上达成一致。开发新语言往往是为了克服...

263100
来自专栏JAVA高级架构开发

Java 11 正式发布,这 8 个逆天新特性教你写出更牛逼的代码

美国时间 09 月 25 日,Oralce 正式发布了 Java 11,这是据 Java 8 以后支持的首个长期版本。

16430
来自专栏编程

PLC编程优化方法,让程序运行提速!

PLC、DCS、仪器仪表、电气技术资料,一网打尽 通过本方法优化可以极大的减少程序语句数,使PLC程序更简洁、可读性更好,由于不需要做耗时的类型转换,程序运行效...

22590

扫码关注云+社区

领取腾讯云代金券