Android:如何使用 quickblox 维护用户在线/离线状态?

Posted

技术标签:

【中文标题】Android:如何使用 quickblox 维护用户在线/离线状态?【英文标题】:Android: How to maintain user online/offline status using quickblox? 【发布时间】:2017-07-03 12:03:29 【问题描述】:

我已在我的应用程序中集成了 quickblox 聊天,并希望保持用户在线和离线状态并尝试了以下选项。

1) 如文档中所述,我已关注此链接 https://quickblox.com/developers/SimpleSample-users-android#Online.5COffline_status,但存在一个问题是它无法明确用户在线状态

2) 使用 Ping 管理器:https://quickblox.com/developers/Android_XMPP_Chat_Sample#Ping_a_user 但它总是给出 QBResponseException

3) QBRoaster:此选项不符合要求。

[注意:我使用的是 quickblox 3.3.1 版]

我已经按如下方式实现了 QBPingManager

    public void checkUserOnlineStatus(String mOpponentName) 
        QBChatService.getInstance().getPingManager().setPingInterval(1);
        Performer<QBUser> qbUser = QBUsers.getUserByLogin(mOpponentName);
        qbUser.performAsync(new QBEntityCallback<QBUser>() 
            @Override
            public void onSuccess(QBUser qbUser, Bundle bundle) 
            final int mOpponentUserId = qbUser.getId();
            final QBPingManager pingManager = QBChatService.getInstance().getPingManager();
            pingManager.pingServer(new QBEntityCallback<Void>() 
                @Override
                public void onSuccess(Void aVoid, Bundle bundle) 
                    pingManager.pingUser(mOpponentUserId, new QBEntityCallback<Void>() 
                        @Override
                        public void onSuccess(Void aVoid, Bundle bundle) 
                            Timber.tag(TAG).w("Opponent User is online ");
                        

                        @Override
                        public void onError(QBResponseException e) 
                            Timber.tag(TAG).e("message(ping user): " + e.getMessage() + "\n localized message: " + e.getLocalizedMessage());
                            e.printStackTrace();
                        
                    );
                

                @Override
                public void onError(QBResponseException e) 
                    Timber.tag(TAG).e("message (ping server): " + e.getMessage() + "\n localized message: " + e.getLocalizedMessage());
                
            );


            

            @Override
            public void onError(QBResponseException e) 
            Timber.tag(TAG).e("Error : " + e.getMessage() + "\n Message :  " + e.getLocalizedMessage());
            
        );
      

感谢您的任何帮助。

【问题讨论】:

【参考方案1】:

在这里我们将找到最后一次看到的时间/日期的在线/离线状态:-

要获得用户的在线/离线状态,您需要发送并确认订阅请求

// to confirm subscription request
QBSubscriptionListener subscriptionListener = new QBSubscriptionListener() 
                @Override
                public void subscriptionRequested(int userId) 
                    try 
                        if (chatRoster != null)
                            chatRoster.confirmSubscription(userId);
                     catch (SmackException.NotConnectedException e) 

                     catch (SmackException.NotLoggedInException e) 

                     catch (XMPPException e) 

                     catch (SmackException.NoResponseException e) 

                    
                
            ;

            chatRoster = QBChatService.getInstance().getRoster(QBRoster.SubscriptionMode.mutual, subscriptionListener);


// to send subscription request
     try 
           chatRoster.subscribe(qbChatDialog.getRecipientId()); //getRecipientId is Opponent UserID
          catch (SmackException.NotConnectedException e) 
           e.printStackTrace();
          

用户在线/离线时发送状态

   QBPresence presence = new QBPresence(QBPresence.Type.online, "I am now available", 1, QBPresence.Mode.available);
    try 
        chatRoster.sendPresence(presence);
     catch (SmackException.NotConnectedException e) 

     catch (Exception e) 
        e.printStackTrace();
    

获取对手用户的存在

QBPresence presence = chatRoster.getPresence(qbChatDialog.getRecipientId());
 if (presence.getType() == QBPresence.Type.online) 
    //online
  else
    //offline
  

识别用户在线状态何时发生变化

QBRosterListener rosterListener = new QBRosterListener() 
        @Override
        public void entriesDeleted(Collection<Integer> userIds) 

        

        @Override
        public void entriesAdded(Collection<Integer> userIds) 

        

        @Override
        public void entriesUpdated(Collection<Integer> userIds) 

        

        @Override
        public void presenceChanged(QBPresence presence1) 
            try 
                int userid = presence1.getUserId();
                int recid = qbChatDialog.getRecipientId();//opponent   user id
                if (userid == recid) 

                    if (presence1.getType() == QBPresence.Type.online)
                        status.setText(getResources().getString(R.string.online));
                    else 

                        status.setText("");
                        String lastseen = getlastseen();
                        if (lastseen.length() > 0) 
                            status.setText(lastseen);
                        
                    
                 else 
                
             catch (Exception e) 

            

        
    ;

获取离线用户的 Last Seen

private String getlastseen() 
        String lastseen = "";
        String appendstring = "";
        try 
            long lastUserActivity = QBChatService.getInstance().getLastUserActivity(qbChatDialog.getRecipientId()); //returns last activity in seconds or error

            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.SECOND, -(int) lastUserActivity);

            String format = "dd MMM yyyy hh:mm a";
            if (DateUtils.isToday(calendar.getTimeInMillis())) 
                format = "hh:mm a";
                appendstring = ChatActivity.this.getResources().getString(R.string.today) + ",";
             else if (isyesterday(calendar.getTimeInMillis())) 
                format = "hh:mm a";
                appendstring = ChatActivity.this.getResources().getString(R.string.yesterday) + ",";
             else if (Calendar.YEAR == Calendar.getInstance().YEAR)
                format = "dd MMM hh:mm aa";

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);

            lastseen = simpleDateFormat.format(calendar.getTime());

         catch (XMPPException.XMPPErrorException | SmackException.NotConnectedException e) 
         catch (Exception e) 
            e.printStackTrace();
        
        return appendstring + lastseen;
    

【讨论】:

【参考方案2】:

您可以使用 QuickBlox Android SDK 自 3.3.3 版以来的新功能,称为“最后一个活动”。您可以调用 QBChatService.getInstance().getLastUserActivity(userId);结果你会得到: - 0 如果对手在线或 - 几秒钟前对手在线或 - 如果用户较新登录聊天,则会出错。

【讨论】:

感谢您的建议,但自从我们启动应用程序以来,它总是返回秒数,因此尽管用户在线,但我无法获得 0 秒。 我需要像 QBPingManager 这样实时检查用户状态的解决方案,例如我想打电话给用户,但我想检查用户当时是在线还是离线。 不幸的是,但 QBChatService.getInstance().getLastUserActivity(userId) 将只返回最后一个用户登录时间..

以上是关于Android:如何使用 quickblox 维护用户在线/离线状态?的主要内容,如果未能解决你的问题,请参考以下文章

Quickblox:使用自定义对象登录 (Android)

Android 上的 Quickblox 视频通话

Quickblox - 如何将通知推送到 Android 和 iOS 平台?

在 Quickblox 中,我们如何在 Android 应用程序 (QBRTCSurfaceView) 中旋转视频(例如 90 度)?

如果用户不在聊天室中,Android quickblox 如何接收消息

没有收到推送通知,quickblox,android