如何在一对一聊天中知道用户在线或离线?

How to know online or offline of user in smack in one to one chat?

我已经尝试过此代码,但所有可用的代码段仍然无法接收用户的在线或离线状态。请帮我。提前致谢。

fun checkStatus() {
    val jid = JidCreate.entityBareFrom("QTX69RGLVQ3VVU8QUB@localhost")

    var roster = Roster.getInstanceFor(connection)
    var availability = roster.getPresence(jid);
    var  userMode = availability.getMode();
    retrieveState_mode(userMode, availability.isAvailable)
}

fun retrieveState_mode(userMode: Presence.Mode, isOnline:Boolean):Int {
    var userState = 0;
    if(userMode == Presence.Mode.dnd) {
        userState = 3;
    } else if (userMode == Presence.Mode.away || userMode == Presence.Mode.xa) {
        userState = 2;
    } else if (isOnline) {
        userState = 1;
    }
    return userState
}

我总是得到 0

监听花名册和状态变化

The typical use of the roster class is to display a tree view of groups and entries along with the current presence value of each entry. As an example, see the image showing a Roster in the Exodus XMPP client to the right.

The presence information will likely change often, and it's also possible for the roster entries to change or be deleted. To listen for changing roster and presence data, a RosterListener should be used. To be informed about all changes to the roster the RosterListener should be registered before logging into the XMPP server. The following code snippet registers a RosterListener with the Roster that prints any presence changes in the roster to standard out. A normal client would use similar code to update the roster UI with the changing information.

Roster roster = Roster.getInstanceFor(con);
roster.addRosterListener(new RosterListener() {
    // Ignored events public void entriesAdded(Collection<String> addresses) {}
    public void entriesDeleted(Collection<String> addresses) {}
    public void entriesUpdated(Collection<String> addresses) {}
    public void presenceChanged(Presence presence) {
        System.out.println("Presence changed: " + presence.getFrom() + " " + presence);
    }
});

请注意,为了接收状态更改事件,您需要订阅用户状态。请参阅以下部分。

Source

第一件事。如果您阅读此文:

https://xmpp.org/extensions/xep-0162.html

你会发现: subscription='both': 您和联系人对彼此的状态信息感兴趣。

因此,如果您的花名册设置为订阅='both',你们俩必须在彼此的花名册中(假设好友请求和双向批准) 收听彼此的在线信息。

所以知道以前,我使用 Smack 的方式是:

//Created presence packet listener
private StanzaListener presencePacketListener;

//In my connection creating
private XMPPTCPConnection createConnection() throws XmppStringprepException {
        XMPPTCPConnectionConfiguration.Builder config =  XMPPTCPConnectionConfiguration.builder();
        .......
        config.setSendPresence(true);
        .......
        return new XMPPTCPConnection(config.build());
}

//Then in login method
public void login() throws SmackInvocationException, XmppStringprepException {
        connect();
        try {
            //Add presencePacketListener to listen for subscribed users (Roster) presence
            con.addSyncStanzaListener(presencePacketListener, new StanzaTypeFilter(Presence.class));
            //Actual login
            .....
            onConnectionEstablished();
        } catch(Exception e) {          
            throw exception;
        }
}

// onConnectionEstablished method
private void onConnectionEstablished() {
        if (state != State.CONNECTED) {         
            sendPacket(new Presence(Presence.Type.available));
        }
}

做的时候

sendPacket(new Presence(Presence.Type.available));

您订阅的花名册中的所有用户都将收到此状态数据包。 这将在

中处理

presencePacketListener

我们之前在登录时注册过。

//PresencePacketListener
public class PresencePacketListener implements StanzaListener {
    private Context context;

    PresencePacketListener(Context context) {
        this.context = context;
    }

    @Override
    public void processStanza(Stanza packet) {
        Presence presence = (Presence)packet;
        Presence.Type presenceType = presence.getType();
        //Do sth with presence
    }
}