1. 程式人生 > 實用技巧 >Smack實現新增好友(二):監聽處理好友申請

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