Smack实现添加好友(二):监听处理好友申请
要实现这一功能有些复杂。
概述
先来理解一些名词或概念吧:
roster:翻译为名册,我想就是好友的意思吧
Subscription:翻译为订阅,在深入了解samck的机制之前,可以理解为添加好友,就是“订阅一个好友”,或者“订阅一个名册”,收到好友申请,可以理解为“收到一个订阅请求”...
presence:用于两个目的:一是通知服务器用户的当前订阅状态,二是对于名册进行订阅和取消订阅
Stanza:翻译为“节”,基于XMPP Stanzas,XMPP Stanzas有Message, IQ and Presence。在这我先理解为Presence也是节的一种吧。
处理订阅消息流程
设置订阅模式->设置对于Presence包的监听(请求添加好友是通过发送Presence包实现的,所以一旦有好友申请,就能接收到Presence包;所以只要设置对Presence包的监听就好了)
①设置订阅处理模式
roster.setSubscriptionMode(Roster.SubscriptionMode subscriptionMode)
默认模式为 Roster.SubscriptionMode.reject_all,表示自动拒绝所有订阅请求。
还可以设置为Roster.SubscriptionMode.accept_all,表示自动接收所有订阅和取消订阅请求。
也可以设置为Roster.SubscriptionMode.manual,则订阅请求被忽略,从而需要手工处理订阅请求。这意味着需要手动注册一个对于presence包(presence packets)的监听器,然后找到所有的类型为Presence.Type.SUBSCRIBE或Presence.Type.UNSUBSCRIBE的presence请求(presence requests)。
在这里,我们需要把处理模式设置为Roster.SubscriptionMode.manual
②添加对presence包的监听
在老版本中大概使用addPacketListener(PacketListener listener, PacketFilter filter)来监听包,在新版本中addPacketListener方法和PacketListener类已被弃用
取而代之的是addAsyncStanzaListener(StanzaListener packetListener, StanzaFilter packetFilter),针对连接,建立一个异步的stanza监听器
conn!!.addSyncStanzaListener(object:StanzaListener{ override fun processStanza(packet: Stanza?) { //判断是Presence包的情况 if(packet is Presence){ var presence:Presence=packet if(presence.type==Presence.Type.subscribe){ println("收到来自${presence.from}的好友申请消息") }else if(presence.type==Presence.Type.available){ println("收到${presence.from}上线消息") }else if(presence.type==Presence.Type.unavailable){ println("收到${presence.from}下线消息") } } } }, object:StanzaFilter{ override fun accept(stanza: Stanza?): Boolean { //在这里可以设置对接收到的包进行过滤 //如 return stanza is Presence,只返回Presence包 //直接return true表示接收所有的包 return true } })
presence.type是枚举常量,具体参考下图
运行
需要两个模拟器吧。或者一个模拟器也行,因为登录的用户A也可以申请添加自己为好友,并且也能监听到presence消息。
如果是两个模拟器的话,就是一个模拟器登录用户A,另一个登录用户B。A请求添加B为好友。这样不可避免要做登录界面了...