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為好友。這樣不可避免要做登入介面了...