Android 高仿微信实时聊天 基于百度云推送

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38799363 ,本文出自:【张鸿洋的博客】

一直在仿微信界面,今天终于有幸利用百度云推送仿一仿微信聊天了~~~

首先特别感谢:weidi1989分享的Android之基于百度云推送IM ,大家可以直接下载;省了很多事哈,本例中也使用了weidi的部分代码,凡是@author way的就是weidi1989的代码~~

1、效果图


核心功能也就上面的两张图了~~~我拿着手机和模拟器聊天,同时感谢群里的兄弟姐妹帮忙测试(好友列表中)。

2、原理

下面通过几个问题来说明下实现的原理:

1、如何实现给某个用户发送消息呢?

其实就是利用百度云提供的REST API,直接通过发送Http请求的形式给某个用户推送一条消息;

网址:http://developer.baidu.com/wiki/index.php?title=docs/cplat/push/api/list

实例:

push_msg
功能
推送消息,该接口可用于推送单个人、一群人、所有人以及固定设备的使用场景。
HTTP请求方式
POST
URL
http[s]://channel.api.duapp.com/rest/2.0/channel/channel

....

2、的确可以实现给某个用户或者一群用户推送消息,那么用户的昵称神马的咋获取的呢,我印象中百度云中没法存这样的数据?

嗯,其实用了一个比较巧妙的方式;在用户首次安装软件的时候,会要求用户填写注册信息,也就是昵称等;当用户填写完毕时,点击登录的时候:

1、发送一条比较特殊的消息,比如这个消息携带一个hello的字段,广播给所有用户;

2、其他用户在收到消息时,首先判断hello这个字段是否有值,有值则说明新用户加入,把该新用户存入本地数据库,然后更新用户列表;

3、其他用户给这个新用户回一条消息,附带一个特殊字段,比如welcome,当新用户收到携带welcome字段的消息时,表明这是对新用户hello的答复,然后将已存在用户添加到该新用户的用户列表。

基本原理就这样了,大家甚至可以利用上述的原理添加一些删除好友的功能;比如当用户点击删除好友,则发送一条特殊消息给被删除的对象,然后对方收到该消息,也将发送发删除。

相信大家在了解原理之后,这个例子瞬间从高大尚变成矮矬穷了,这尼玛,so easy,谁不会啊~~~


3、核心代码解析

由于代码量还是相当大的,也不想拆成几篇博客,所以准备将核心代码进行讲解下,其他的大家自己看源码~

关于这个例子的主界面,可以参考: 高仿微信5.2.1主界面架构 包含消息通知

关于百度云推送的入门,可以参考:Android推送 百度云推送 入门篇

好了,最主要就是收到百度云推送的Receiver

1、onBind

首先是用户第一次登录时候绑定的回调

@Overridepublic void onBind(final Context context, int errorCode, String appid,String userId, String channelId, String requestId){String responseString = "onBind errorCode=" + errorCode + " appid="+ appid + " userId=" + userId + " channelId=" + channelId+ " requestId=" + requestId;Log.e(TAG, responseString);if (errorCode == 0){SharePreferenceUtil util = PushApplication.getInstance().getSpUtil();util.setAppId(appid);util.setChannelId(channelId);util.setUserId(userId);} else// 如果网络正常,则重试{if (NetUtil.isNetConnected(context)){T.showLong(context, "启动失败,正在重试...");new Handler().postDelayed(new Runnable(){@Overridepublic void run(){PushManager.startWork(context,PushConstants.LOGIN_TYPE_API_KEY,PushApplication.API_KEY);}}, 2000);// 两秒后重新开始验证} else{T.showLong(context, R.string.net_error_tip);}}// 回调函数for (int i = 0; i < bindListeners.size(); i++)bindListeners.get(i).onBind(userId, errorCode);}
初次绑定的时候,如果绑定成功则使用SharedPreferences存储userId,channelId等数据

然后回调:bindListeners.get(i).onBind(userId, errorCode);给所有注册该事件的发出通知

下面看listener.onBind

/*** 收到通知*/@Overridepublic void onBind(String userId, int errorCode){Log.e("TAG", "Login Activity onBind ");if (errorCode == 0){Log.e("TAG", "Login Activity onBind success ");// 如果绑定账号成功,由于第一次运行,给同一tag的人推送一条新人消息User u = new User(mSpUtil.getUserId(), mSpUtil.getChannelId(),mSpUtil.getNick(), mSpUtil.getHeadIcon(), 0);mUserDB.addUser(u);// 把自己添加到数据库Message firstSendMsg = new Message(System.currentTimeMillis(), "");firstSendMsg.setHello("hello");task = new SendMsgAsyncTask(mGson.toJson(firstSendMsg), "");task.setOnSendScuessListener(new OnSendScuessListener(){@Overridepublic void sendScuess(){if (mLoadingDialog != null && mLoadingDialog.isVisible())mLoadingDialog.dismiss();mHandler.removeCallbacks(mConnTimeoutCallback);finish();Intent intent = new Intent(LoginActivity.this,MainActivity.class);startActivity(intent);}});task.send();}}
首先将自己保存到本地数据库,然后发送一个Message给所有的用户,设置一个特殊字段hello;也就是上述的原理分析中的部分~


2、onMessage

收到百度云推送的Receiver中的onMessage

@Overridepublic void onMessage(Context context, String message,String customContentString){String messageString = "收到消息 message=\"" + message+ "\" customContentString=" + customContentString;Log.e(TAG, messageString);Message receivedMsg = PushApplication.getInstance().getGson().fromJson(message, Message.class);// 对接收到的消息进行处理parseMessage(receivedMsg);}/*** 消息:1、携带hello,表示新人加入,应该自动回复一个world 消息; 2、普通消息;* * @param msg*/private void parseMessage(Message msg){String userId = msg.getUserId();// 自己的消息if (userId.equals(PushApplication.getInstance().getSpUtil().getUserId()))return;if (checkHasNewFriend(msg) || checkAutoResponse(msg))return;// 普通消息UserDB userDB = PushApplication.getInstance().getUserDB();User user = userDB.selectInfo(userId);// 漏网之鱼if (user == null){user = new User(userId, msg.getChannelId(), msg.getNickname(), 0, 0);userDB.addUser(user);// 通知监听的面板for (onNewFriendListener listener : friendListeners)listener.onNewFriend(user);}if (msgListeners.size() > 0){// 有监听的时候,传递下去for (int i = 0; i < msgListeners.size(); i++)msgListeners.get(i).onNewMessage(msg);} else// 当前没有任何监听,即处理后台状态{// 将新来的消息进行存储ChatMessage chatMessage = new ChatMessage(msg.getMessage(), true,userId, msg.getHeadIcon(), msg.getNickname(), false,TimeUtil.getTime(msg.getTimeSamp()));PushApplication.getInstance().getMessageDB().add(userId, chatMessage);showNotify(msg);}}/*** 检测是否是自动回复* * @param msg*/private boolean checkAutoResponse(Message msg){String world = msg.getWorld();String userId = msg.getUserId();if (!TextUtils.isEmpty(world)){User u = new User(userId, msg.getChannelId(), msg.getNickname(),msg.getHeadIcon(), 0);PushApplication.getInstance().getUserDB().addUser(u);// 存入或更新好友// 通知监听的面板for (onNewFriendListener listener : friendListeners)listener.onNewFriend(u);return true;}return false;}/*** 检测是否是新人加入* * @param msg*/private boolean checkHasNewFriend(Message msg){String userId = msg.getUserId();String hello = msg.getHello();// 新人发送的消息if (!TextUtils.isEmpty(hello)){Log.e("checkHasNewFriend", msg.getUserId());// 新人User u = new User(userId, msg.getChannelId(), msg.getNickname(),msg.getHeadIcon(), 0);PushApplication.getInstance().getUserDB().addUser(u);// 存入或更新好友T.showShort(PushApplication.getInstance(), u.getNick() + "加入");// 给新人回复一个应答Message message = new Message(System.currentTimeMillis(), "");message.setWorld("world");new SendMsgAsyncTask(PushApplication.getInstance().getGson().toJson(message), userId);// 通知监听的面板for (onNewFriendListener listener : friendListeners)listener.onNewFriend(u);return true;}return false;}

当收到一个新的消息:

1、首先判断是不是自己发的,是,忽略;

2、判断是否携带hello字段,代表新人加入,携带,则保存到好友列表,且回复一个携带welcome字段的消息;

3、判断是否包含welcome字段,包含,存入好友列表

4、不是1、2、3则肯定是普通消息,将消息保存到本地数据库,然后为所有设置消息监听的发送回调即可~


MainTabFriends.java用户列表中收到新消息的回调:

/*** 收到新消息时*/@Overridepublic void onNewMessage(Message message){// 如果是自己发送的,则直接返回if (message.getUserId() == mSpUtils.getUserId())return;// 如果该用户已经有未读消息,更新未读消息的个数,并通知更新未读消息接口,最后notifyDataSetChangedString userId = message.getUserId();if (mUserMessages.containsKey(userId)){mUserMessages.put(userId, mUserMessages.get(userId) + 1);} else{mUserMessages.put(userId, 1);}mUnReadedMsgs++;notifyUnReadedMsg();// 将新来的消息进行存储ChatMessage chatMessage = new ChatMessage(message.getMessage(), true,userId, message.getHeadIcon(), message.getNickname(), false,TimeUtil.getTime(message.getTimeSamp()));mApplication.getMessageDB().add(userId, chatMessage);// 通知listview数据改变mAdapter.notifyDataSetChanged();}

1、如果是自己发的不做任何处理

2、如果当前消息发送用户已有未读消息,则更新该用户未读消息个数(用户Item上显示未读消息通知数),更新所有未读消息总和(朋友Tab上显示未读消息总和),然后存储该消息

3、刷新界面


ChattingActivity.java聊天界面的新消息回调

@Overridepublic void onNewMessage(Message message){// 获得回复的消息if (mFromUser.getUserId().equals(message.getUserId())){ChatMessage chatMessage = new ChatMessage();chatMessage.setComing(true);chatMessage.setDate(new Date(message.getTimeSamp()));chatMessage.setMessage(message.getMessage());chatMessage.setUserId(message.getUserId());chatMessage.setNickname(message.getNickname());chatMessage.setReaded(true);mDatas.add(chatMessage);mAdapter.notifyDataSetChanged();mChatMessagesListView.setSelection(mDatas.size() - 1);// 存入数据库,当前聊天记录mApplication.getMessageDB().add(mFromUser.getUserId(), chatMessage);}}

首先判断是否是正在聊天的用户发的消息,如果是,直接存入数据库,刷新聊天界面;



好了,细节也不展开描述了,大家自己看源码,bug肯定有,发现bug可以直接留言,方便其他学习的童鞋,也方便我了,多谢~~~~~~~~~~~~~~

ps:最近状态不好,我要去喝脉动~~~~


源码点击下载  大家可以先安装压缩文件里面的apk测试下,这样就可以发现别的伙伴了~~~


源码点击下载 补充了一下那个BadgeView的项目~~~





 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/64093.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LSTM笔记

RNN, LSTM, GRU模型的作用, 构建, 优劣势比较,attention机: https://blog.csdn.net/sinat_28015305/article/details/109355828?ops_request_misc%257B%2522request%255Fid%2522%253A%2522167903492816800182195114%2522%252C%2522scm%2522%253A%252220140713.130102334..%252…

手把手教你生成正式签名的APK文件

一&#xff0c;使用Android Studio生成 1. 2. 3.如果先前没有则先点Create new 4. 5. 6. 7.点击Finish 8. 二.使用Gradle生成&#xff1a; 1.在安卓闭包中加上 上图紫色字体跟第一种生成方式填的内容一样&#xff0c;这里我把它隐藏起来了 注&#xff1a;一定要放在buildTy…

Android购物软件制作(毕业设计)

本篇博客为了展示自己的实战结果&#xff0c;完成了对淘宝功能的实现&#xff0c;主要用于毕业设计的完成。 首先贴图以表效果&#xff0c;虽然拉跨&#xff0c;但是毕业够用&#xff01; 首先&#xff1a;要开发一款淘宝类的APP&#xff0c;其实分为两种&#xff0c;一种是淘…

[干货]手把手教你写一个安卓app

摘要&#xff1a;最近有很多小伙伴在后台留言&#xff1a;Android Studio。我想大家是想写一个手机app&#xff0c;前面已经分享了在QT上如何写一个安卓蓝牙app&#xff0c;虽然qt可以做app&#xff0c;但是比起Android Studio还是差很多。这里介绍一种快速入门的方法来制作一款…

Android手机通讯录制作

Android手机通讯录制作 要求样图展示代码1.创建数据库2.主界面MainActivityCustomAdapter.javaactivity_main.xml 3.添加联系人AddContacts.java(添加界面)addactivity.xml 要求 设计一个基于Android的手机通讯录&#xff0c;此通讯录包括添加、搜索、修改、删除联系人的功能。…

安卓APP源码和设计报告——个人通讯录

摘 要 随着移动设备制造技术和移动通信网络的迅猛发展,全球手机用户日益增加,手机成为了很多人日常生活中必不可少的一部分,手机业在日益发展的同时,人们对手机的功能需求和体验需求也越来越高,因此各种智能手机相继而出&#xff0c;当前市场上最流行的智能手机的操作系统非An…

【视觉基础篇】12 # 如何使用滤镜函数实现美颜效果?

说明 【跟月影学可视化】学习笔记。 如何理解像素化&#xff1f; 像素化 所谓像素化&#xff0c;就是把一个图像看成是由一组像素点组合而成的。每个像素点负责描述图像上的一个点&#xff0c;并且带有这个点的基本绘图信息。 像素点是怎么存储的&#xff1f; Canvas2D 以…

C++ / Opencv 简单实现美颜效果(瘦脸、大眼、磨皮等)

最近项目需要用到美颜的一些效果&#xff0c;因此开始接触opencv 计算机视觉库,在腾讯课堂上找到一个简单且免费的入门视频《Opencv4 快速入门视频30讲》&#xff0c;看完视频后&#xff0c;初步才对opencv 有一个比较清晰的概念和基本用法。 接下来就是开始对美颜的一些初步接…

Ps人像磨皮皮肤美白插件哪个好_安装教程

今天这个PS插件挺好用的&#xff0c;我们可以用它快速给人像照片磨皮、皮肤美白、上妆等功能&#xff0c;还是非常方便我们后期修图的&#xff0c;有需要这个插件的可以至陌鱼社区瞧一下。插件支持:Adobe PhotoshopCC2015 - CC2018,这里我们用Adobe PhotoshopCC2018做为演示&am…

对皮肤美白算法的一些研究

本篇博文来自博主Imageshop&#xff0c;打赏或想要查阅更多内容可以移步至Imageshop。 转载自&#xff1a;https://www.cnblogs.com/Imageshop/p/3843635.html 侵删 皮肤美白是现在任何一款流行的美颜软件必备的功能之一&#xff0c;不过你如果在互联网上搜索关于美白算法&a…

Portraiture4.0最新PS专属修图磨皮美白插件

作为PS的插件&#xff0c;被众多照片后期高手使用&#xff0c;评价颇高。主要原因在于它操作简便、磨皮效果好、软件很小&#xff0c;特别是它可以自动感应皮肤区域磨皮&#xff0c;只对皮肤作用更令人称奇的是&#xff1a;Portraiture 磨皮能保留下细小的毛孔和皮肤质感&#…

photoshop ps 美白 去污 磨皮 方法

目录 1.美白 2.去污 3.磨皮 1.美白 使用PS打开照片&#xff0c;然后复制一个图层。 复制的快捷方式就是 CTRLJ 复制的图层&#xff0c;把混合模式选择在“滤色”&#xff0c;然后调整旁边的透明度。 这个过程其实是把照片调亮。 完成之后&#xff0c;合并图层。合并图层的…

图像滤镜艺术---人脸编辑(五官微调+瘦脸美型)

写本文的目的&#xff0c;实际上是对目前人脸美型这一块技术做个总结&#xff0c;跟大家 分享一下&#xff01; 目前提到美颜算法&#xff0c;大家都会想到磨皮美白 /大眼瘦脸&#xff0c;实际上做好 美颜这件事情&#xff0c;关乎的不仅仅是这些&#xff0c;还有五官的协调比…

ps美白磨皮处理第三方插件portraiture

ps的功能这么强大&#xff0c;其美白磨皮方法当然不止一种。本文就给大家细数一下ps美白磨皮常用的几种方法。在各种方法中&#xff0c;插件法的操作更为简单&#xff0c;效果也更好&#xff0c;因此我们还会介绍ps磨皮美白插件哪个好。事不宜迟&#xff0c;一起来看看吧。 一…

初中英语知识水平测试软件,初中英语学科知识与能力模拟测试一

一、单项选择题(本大题共30小题,每小题2分,共60分) 在每小题列出的四个备选项中选择一个最佳答案,错选、多选或未选均无分。 *1. Which of the following doesnt contain liaison&#xff1f; A. Put it on, please B. Not at all C. Please pick it up D. Great minds…

轻松完成公司数据分析、业务数据探查的秘诀

2022年即将结束&#xff0c;您企业经营目标达成情况如何&#xff1f;是否可以快速对企业进行数据体检分析&#xff1f;天通眼带您快速了解企业各个维度的经营状况。 PART 01 年度计划检视 2022年还剩余1个月&#xff0c;您企业年度目标达成情况如何&#xff1f;每个月、每个季度…

数据分析真的很火吗?真的有很多企业需要这样的岗位吗?求大佬指点。

“我是去年毕业的&#xff0c;因为疫情影响&#xff0c;整个就业环境都很不好&#xff0c;很多企业都裁员了。加上疫情三年基本都是玩过去&#xff0c;也没啥一技之长&#xff0c;就业就更难了。听说现在做数据分析的人很多&#xff0c;我身边的朋友都在转行做数据分析。 其实…

数据分析师应该了解的数据湖

数据湖 数据湖是一个集中式存储库&#xff0c;允许您以任意规模存储所有结构化和非结构化数据。您可以按原样存储数据&#xff08;无需先对数据进行结构化处理&#xff09;&#xff0c;并运行不同类型的分析 – 从控制面板和可视化到大数据处理、实时分析和机器学习&#xff0c…

数据分析师获取数据的方式有哪些?

1、外部购买数据 有很多公司或者平台是专门做数据收集和分析的&#xff0c;企业会直接从那里购买数据或者相关服务给数据分析师&#xff0c;这是一种常见的获取数据的方式之一。 2、网络爬取数据 除了购买数据以外&#xff0c;数据分析师还可以通过网络爬虫从网络上爬取数据…