要實現這一功能有些複雜。
概述
先來理解一些名詞或概念吧:
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為好友。這樣不可避免要做登錄界面了...