转载请标明出处: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
首先是用户第一次登录时候绑定的回调
@Override
public 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()
{
@Override
public 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
/**
* 收到通知
*/
@Override
public 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()
{
@Override
public 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
@Override
public 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用户列表中收到新消息的回调:
/**
* 收到新消息时
*/
@Override
public void onNewMessage(Message message)
{
// 如果是自己发送的,则直接返回
if (message.getUserId() == mSpUtils.getUserId())
return;
// 如果该用户已经有未读消息,更新未读消息的个数,并通知更新未读消息接口,最后notifyDataSetChanged
String 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聊天界面的新消息回调
@Override
public 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的项目~~~
分享到:
相关推荐
为了实现实时聊天,开发者通常会采用长轮询、WebSocket或者基于第三方服务(如百度云推送)的推送机制。在Android中,可能需要使用HttpURLConnection或者OkHttp等库进行网络请求,同时处理异步任务和线程管理,确保...
综上所述,"android高仿微信聊天界面"项目涵盖了Android应用开发的多个重要知识点,包括UI设计、传感器交互、网络通信、数据存储和性能优化等,对于提升开发者在实际项目中的技能和经验具有很高的价值。通过这个项目...
在本文中,我们将深入探讨如何基于Android Studio开发一个高仿微信的应用程序。Android Studio是Google提供的官方集成开发环境(IDE),特别适用于Android应用的开发。它提供了丰富的工具集,包括代码编辑器、调试器...
在Android应用开发中,创建一个高仿微信的聊天界面是一项常见的任务,这涉及到对用户界面设计的深入理解和熟练掌握Android的UI组件。本项目主要基于ListView进行实现,ListView是Android中用于显示大量数据的列表...
在Android开发中,仿微信聊天界面是一个常见的需求,它涉及到许多关键技术和组件的集成。这个项目可能包括消息列表的展示、输入框设计、表情键盘、发送按钮、未读消息提示等多个方面。以下是一些相关的重要知识点: ...
此外,考虑到用户体验,消息推送的实时性与流畅性也是需要重点优化的部分。 社交功能的实现,如添加好友、创建群聊、朋友圈分享,往往涉及到复杂的业务逻辑。这些功能的实现需要处理用户认证、数据同步、权限管理等...
通过这个项目,开发者可以学习到如何设计和实现聊天、朋友圈、个人信息展示、好友添加、消息推送等功能。 【标签解析】 由于未提供具体的标签,我们可以推测这个项目涉及的关键技术标签可能包括:Android Studio、...
在IT行业中,构建一个“高仿微信实时语音聊天dialog”是一项常见的需求,特别是在移动应用开发领域。微信作为全球用户量巨大的社交平台,其实时语音聊天功能的实现方式和交互设计备受开发者关注。本文将深入探讨如何...
android高仿微信朋友圈
高仿微信源码,友友们我会更新更多的源码和大家分享,希望大家喜欢。
Android 超高仿微信图片选择器完整实例Android 超高仿微信图片选择器完整实例Android 超高仿微信图片选择器完整实例Android 超高仿微信图片选择器完整实例Android 超高仿微信图片选择器完整实例Android 超高仿微信...
在Android平台上,构建一个高仿微信聊天界面是一个常见的任务,涉及到UI设计、数据管理以及用户交互等多个方面。本文将深入探讨实现这一目标的关键知识点,并基于提供的"demo"压缩包文件来解析实现步骤。 首先,...
9. **推送服务**:集成第三方推送服务如Firebase Cloud Messaging (FCM) 或极光推送,实现实时消息推送,即使应用在后台也能接收到新消息通知。 10. **性能优化**:通过异步任务、内存管理、网络优化等手段提升应用...
在Android平台上,构建一个类似微信的聊天界面是一个常见的需求,涉及到多个关键技术点。这个项目,"HRChatDemo",显然就是一个实现这一目标的示例应用。让我们深入探讨一下其中涉及的关键技术及其细节。 首先,...
PullDownListView高仿微信下拉眼睛出现动画,动画自定义PullDownListView, pullDownListView.setOnPullHeightChangeListener设置下拉高度监听,onTopHeightChange() onBottomHeightChange(),onRefreshing()...
在Android开发中,"Android高仿微信朋友圈"是一项常见的需求,尤其对于那些希望构建社交功能的App来说。这个项目旨在创建一个与微信朋友圈相似的功能模块,让用户能够在自己的应用内分享内容,浏览他人分享,点赞,...