初识Xabber
git地址:https://github.com/redsolution/xabber-android
Xabber是一款基于xmpp协议的多账号即时通讯App。关于XMPP协议就不多做说明。网上一大堆资料可以查询。最大的好处就是扩展性强。可以参考这篇文章:https://blog.youkuaiyun.com/wulex/article/details/83715175。
运行Xabber注意事项
1.使用最新版本的开发环境
2.clone代码到本地。
3.clone另外一个项目MemorizingTrustManager到本地引用为xabber的moudle.
4.将build.gradle中的dev,beta等productFlavors注释掉只留下open即可编译成功。
5.账号注册:app里的注册使用了google服务,而大多数的国产机都是没有的。可以直接到登录页里有网页注册的入口。注册号以后就可以使用了。
项目结构
Xabber包含了两个moudle。emoji和MemorizingTrustManager。emoji表情都熟悉。MemorizingTrustManager是用来做SSL证书的。项目的主要代码在main目录下分为android和xmpp。我们暂时只需要关注android下面的代码即可。打开android目录可以看到四大组件的区分模块还是很明显的。data目录下主要做数据操作,receiver,ui,service基本就是四大组件的分类了。再加上一个util工具包,一个presentation自定义View。
增加红包功能
XML是XMPP数据结构的核心,通过扩展xml标签,我们可以完成很多功能。运行项目以后发现真正通讯模块里面只有发文字消息和图片消息。这里我们增加发红包功能,领红包和消息撤回三个功能。以发红包为例先上图:
要实现这样一个功能,大致的流程是:
首先。对xml进行扩展。继承元素扩展类ExtensionElement 。定义好标签及其属性。
public static class RedEnvelopeType implements ExtensionElement {
public static final String NAMESPACE = "urn:xmpp:redenvelope-element";
//自定义的标签名
public static final String ELEMENT = "redenvelope";
//预留的类型字段
private String type;
//红包祝福语
private String remarks;
//红包金额
private String money;
public RedEnvelopeType(String type, String remarks, String money) {
this.type = type;
this.remarks = remarks;
this.money = money;
}
@Override
public String getElementName() {
return ELEMENT;
}
@Override
public CharSequence toXML() {
XmlStringBuilder xml = new XmlStringBuilder(this);
// Add attribute
xml.optAttribute("type", getType());
xml.optAttribute("remarks", remarks);
xml.optAttribute("money", String.valueOf(money));
xml.rightAngleBracket();
xml.append("红包{" + remarks + "]");
xml.closeElement(this);
return xml;
}
@Override
public String getNamespace() {
return NAMESPACE ;
}
}
有了扩展的标签,我们就可以发送扩展信息了。当然在发送之前也要做些UI及数据库方面的工作,如:输入红包金额,祝福语。将要发送的信息更新到聊天页面列表。这里更新聊天列表需要注意,我们平时更新recycleView都是给adapter增加一条数据然后调用刷新功能。而这个demo用了Realm数据库保存发送的信息,Realm数据库可以对RealmResults监听数据变化,所以我们只需要往Realm数据库里增删改查,在数据变化监听方法里调用刷新功能就好了。切勿重复添加数据,参考类:RealmRecyclerViewAdapter。数据库方面需要注意数据库版本迁移,此demo消息的数据库在MessageDatabaseManager里面管理,其他的数据用RealmManager管理,版本迁移的时候不要弄错。
做完准备工作就可以构造要发送的消息了。
//创建一条消息
message = createMessagePacket(text, messageItem.getStanzaId());
//如果是要发送红包消息 就将红包标签及其属性以DataForm加入消息扩展中
if (messageItem.getMessage_type() == MessageItem.MessageType.REDENVELOPE) {
DataForm dataForm = DataFormManager.redEnvelopeDataFrom(messageItem);
message.addExtension(dataForm);
}
public static DataForm redEnvelopeDataFrom(MessageItem messageItem) {
DataForm dataForm = new DataForm(DataForm.Type.form);
for (RedEnvelope redEnvelo