使用Smack制作聊天应用, 尝试获取用户的上次查看时间,但获得以下异常
org.jivesoftware.smack.XMPPException$XMPPErrorException: XMPPError: subscription-required - auth
代码:
public void getLastSeen(String JID) {
LastActivityManager mLastActivity = LastActivityManager.getInstanceFor (connection);
try {
try {
mLastActivity.getLastActivity (JID);
Log.e (TAG, "" + mLastActivity.getLastActivity (JID));
} catch (SmackException.NoResponseException e) {
e.printStackTrace ( );
}
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace ( );
} catch (SmackException.NotConnectedException e) {
e.printStackTrace ( );
}
}
在以下行
上获得上述异常 mLastActivity.getLastActivity (JID);
有人知道为什么会遇到这个例外吗?
答案 0 :(得分:2)
可能因为您需要订阅联系人的状态才能检索上一个活动。
答案 1 :(得分:0)
首先,一旦建立 xmpp 连接,您需要设置名册:
private fun setupRoaster() {
if (conn1 == null) {
Timber.d("setupRoaster failed , due to connection is null $conn1")
} else {
conn1?.let {
roster = Roster.getInstanceFor(conn1)
roster?.subscriptionMode = Roster.SubscriptionMode.manual
roster?.addRosterListener(this)
Timber.d("setupRoaster roster?.entryCount : ${roster?.entryCount}")
roster?.addSubscribeListener(object:SubscribeListener{
override fun processSubscribe(
from: Jid?,
subscribeRequest: Presence?
): SubscribeListener.SubscribeAnswer {
Timber.d("setupRoaster SubscribeListener calledback Approved")
return SubscribeListener.SubscribeAnswer.Approve
}
})
if(BuildConfig.DEBUG){
//Here we are observed all the roster contacts and status
roster?.let {
for(ros in it.entries){
Timber.d("setupRoaster Info isSubscriptionPending :: ${ros.isSubscriptionPending} isApproved :: ${ros.isApproved} type :: ${ros.type} isSubscribedToMyPresence : ${roster?.isSubscribedToMyPresence(ros.jid)} ros.jid : ${ros.jid}")
//ros.isSubscriptionPending
}
}
}
Timber.d("setupRoaster success")
}
Timber.d("setupRoaster failed $conn1")
}
}
要将任何用户添加到您的名册中,请使用以下代码:
override suspend fun addContactToRoster(toUserId: String, name: String) {
Coroutines.io {
Timber.d("addContactToRoster 1 $toUserId")
if(roster == null){
setupRoaster()
}
if (roster != null) {
Timber.d("addContactToRoster 2 roster?.isLoaded : ${roster?.isLoaded} ")
try {
roster?.let {
if(it.isLoaded && !it.isSubscribedToMyPresence(getJabberId(toUserId))){
val presence = Presence(Presence.Type.subscribe)
presence.setTo(getJabberId(toUserId))
presence.setType(Presence.Type.subscribed)
conn1?.sendStanza(presence)
roster?.createEntry(getJabberId(toUserId), name, null)
}
}
Timber.d("addContactToRoster Contact added to roster successfully")
} catch (e: SmackException.NotLoggedInException) {
Timber.d("addContactToRoster SmackException.NotLoggedInException called ${e.message} conn1?.isConnected ${conn1?.isConnected} conn1.isAuthenticated : ${conn1?.isAuthenticated}")
login()
} catch (e: SmackException.NoResponseException) {
Timber.d("addContactToRoster SmackException.NoResponseException called ${e.message} conn1?.isConnected ${conn1?.isConnected} conn1.isAuthenticated : ${conn1?.isAuthenticated}")
} catch (e: SmackException.NotConnectedException) {
Timber.d("addContactToRoster SmackException.NotConnectedException called ${e.message} conn1?.isConnected ${conn1?.isConnected} conn1.isAuthenticated : ${conn1?.isAuthenticated}")
}
} else {
Timber.d("addContactToRoster Roster not initilized,")
Timber.d("addContactToRoster May when user comes first time at that time internet not available so connection not established")
}
}
}
一旦用户成功添加到名册和接收者接受您的订阅,您就可以使用以下方法最后一次获取活动/最后一次看到:
fun getLastActivity(userId: String): String? {
Timber.d("XMPP :: getLastActivity $userId called conn1 : $conn1")
val jabberId = getJabberId(userId)
jabberId?.let {
Timber.d("XMPP :: getLastActivity 1 ${jabberId}")
conn1?.let {
Timber.d("XMPP :: getLastActivity 2")
if (it.isConnected && it.isAuthenticated) {
Timber.d("XMPP :: getLastActivity 3")
try {
val lastActivityManager: LastActivityManager =
LastActivityManager.getInstanceFor(conn1)
//val jid : Jid = JidCreate.from("u1304@quantumpigeon.com");
val status = lastActivityManager.isLastActivitySupported(jabberId)
val lastStatus = lastActivityManager.getLastActivity(jabberId)
Timber.d(
"XMPP :: lastStatus.toString $lastStatus \n lastStatus.lastActivity ${lastStatus.lastActivity} " +
"\n lastStatus.idleTime : ${lastStatus.idleTime} \n lastStatus.message : ${lastStatus.message} \n lastStatus.statusMessage : ${lastStatus.statusMessage}"
)
val milliSeconds =
applicationContext.getTrueTimeNow().time - (lastStatus.lastActivity * 1000)
//val lastSeen = getDate(milliSeconds, "dd/MM/yyyy hh:mm:ss.SSS")
val lastSeen = getLastSeen(milliSeconds)
Timber.d("XMPP :: isLastActivitySupported : $status lastStatus : $lastStatus LastSeen : $lastSeen")
return lastSeen
} catch (e: XMPPException.XMPPErrorException) {
Timber.d("XMPP :: Error in get last activity : ${e.message}")
} catch (e: SmackException.NoResponseException) {
Timber.d("XMPP :: SmackException.NoResponseException. : ${e.message}")
} catch (e: SmackException.NotConnectedException) {
Timber.d("XMPP :: SmackException.NotConnectedException. : ${e.message}")
}
} else {
Timber.d("XMPP :: handleNotConnectedException : ${it.isConnected} or authenticated ${it.isAuthenticated}")
// handleNotConnectedException()
}
Timber.d("XMPP :: Connection not connected : ${it.isConnected} or authenticated ${it.isAuthenticated}")
}
Timber.d("XMPP :: Connection not established $conn1")
}
return null
}