Reputation: 1302
Making Chat App using Smack , Try to get the Last Seen time of user but getting following Exception
org.jivesoftware.smack.XMPPException$XMPPErrorException: XMPPError: subscription-required - auth
Code :
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 ( );
}
}
getting above Exception on following line
mLastActivity.getLastActivity (JID);
Anybody know why getting this exception ?
Upvotes: 0
Views: 367
Reputation: 1623
First you need to setup roster once xmpp connection established :
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")
}
}
To add any user into your roster use below code :
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")
}
}
}
Once user successfully added to roster and receiver accept your subscription than you can last get activity/last seen by using below method :
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("[email protected]");
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
}
Upvotes: 0
Reputation: 24043
Likely because you need to be subscribed to the contact's presence in order to retrieve the last activity.
Upvotes: 3