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

转载请标明出处:,本文出自:【张鸿洋的博客】

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

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

1、效果图

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

2、原理

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

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

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

网址:?title=docs/cplat/push/api/list

实例:

push_msg功能推送消息,该接口可用于推送单个人、一群人、所有人以及固定设备的使用场景。HTTP请求方式POSTURLhttp[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则肯定是普通消息,将消息保存到本地数据库,然后为所有设置消息监听的发送回调即可~

寂寞时,想想我的影子,我会在远方给你一个微笑;难过时,

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

相关文章:

你感兴趣的文章:

标签云: