Real Time Updates
Real-time update is the most important part in building an instant chat messaging application. Applozic provides very simple methods to register and listen for the events to update them on the UI. The publish-subscribe pattern is used here in which the senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers, but instead categorize published messages into classes without knowledge of which subscribers, if any, there may be. Similarly, subscribers express interest in one or more classes and only receive messages that are of interest, without knowledge of which publishers, if any, there are.
Connecting to publish
Use the below code to connect to publish.
There are two ways to connect using applozic methods :
A) Connect and Verifying token internally and shows the loader with the message passed in the below method .
Applozic.connectPublishWithVerifyToken(context, "Please wait...");
Applozic.connectPublishWithVerifyToken(context, "Please wait...")
B) Connect publish and Show your own loading indicator
if (AlAuthService.isTokenValid(context)) {
Applozic.connectPublish(context);
} else {
// Getting new token from server and on success call the connect publish will be called.
AlAuthService.refreshToken(context, new AlCallback() {
@Override
public void onSuccess(Object response) {
Applozic.connectPublish(context);
}
@Override
public void onError(Object error) {
}
});
}
if (AlAuthService.isTokenValid(context)) {
Applozic.connectPublish(context)
} else {
// Getting new token from server and on success call the connect publish will be called.
AlAuthService.refreshToken(context, object : AlCallback {
override fun onSuccess(response: Any) {
Applozic.connectPublish(context)
}
override fun onError(error: Any) {}
})
}
Disconnecting from publish
Use the below code to disconnect from publish.
Applozic.disconnectPublish(context);
Applozic.disconnectPublish(context)
Note
The connect and disconnect must be called only once during the lifecycle of an activity/fragment. The best place would be
onCreate()
forconnectPublish
andonDestroy()
fordisconnectPublish
. Once a user has called theconnectPublish
method, he will be marked as online until thedisconnectPublish
method is called.
Handling the UI listener
After the publish has been connected, you will need to register the ApplozicUIListener
to listen for different events that occur in real time. Follow these steps to register the listener:
- Implement
ApplozicUIListener
in your activity/fragment. - Register the listener when user enters the chat fragment/activity
- Update the events received from the callback on the UI
- Unregister the listener when user leaves the chat fragment/activity
Implement ApplozicUIListener
in your activity/fragment
ApplozicUIListener
in your activity/fragmentpublic class ConversationActivity extends AppCompatActivity implements ApplozicUIListener{
}
class ConversationActivity : AppCompatActivity(), ApplozicUIListener {
}
Register the listener
You can register the listener using the below code. Every instance of the listener must be registered with a unique ID. In the below code we are registering the listener using id as "listener2":
AlEventManager.getInstance().registerUIListener("listener2", this);
AlEventManager.getInstance().registerUIListener("listener2", this)
Updating the events on the UI
You need to override all the methods of the ApplozicUIListener
in your activity/fragment that implements this listener. The methods are described below:
@Override
public void onMessageSent(Message message) {
//When a message has been sent
}
@Override
public void onMessageReceived(Message message) {
//when a new message is received. You could reload the message list or add this message to the existing message list to update this message on UI.
}
@Override
public void onLoadMore(boolean loadMore) {
//If message list pagination has been called
}
@Override
public void onMessageSync(Message message, String key) {
//If a message has been synced with server.
}
@Override
public void onMessageDeleted(String messageKey, String userId) {
//If a message was deleted successfully for a user
}
@Override
public void onMessageDelivered(Message message, String userId) {
//If a message has been delivered to a User with userId
}
@Override
public void onAllMessagesDelivered(String userId) {
//If all the pending messages have been delivered with to the User
}
@Override
public void onAllMessagesRead(String userId) {
//If all messages have been read by the User
}
@Override
public void onConversationDeleted(String userId, Integer channelKey, String response) {
//If a conversation thread has been deleted. If channelKey is not null, it is for the group else it is for the user.
}
@Override
public void onUpdateTypingStatus(String userId, String isTyping) {
//If the typing status has been updated for the user.
//if isTyping is 1, the user has started typing
//if isTyping is 0, the user has stopped typing
}
@Override
public void onUpdateLastSeen(String userId) {
//Will be received if the User's last seen has been updated or if login user blocked some one or blocked by some one to login user
ContactDatabase service = new ContactDatabase(this);
Contact contact = service.getContactById(userId);
if (contact != null) {
Log.i("Blocked"," Is Login user blocked the userID ? :" + contact.getUserId() + "blocked ?" + contact.isBlocked());
Log.i("Blocked BY"," Is Some one blocked the login user ? :" + contact.getUserId() + "blockedBy ?" + contact.isBlockedBy());
}
}
@Override
public void onMqttDisconnected() {
//call connectPublish method here
}
@Override
public void onMqttConnected() {
//Will be received when Mqtt connection is successfull
}
@Override
public void onUserOnline() {
//Will be received when the logged in user goes online(when connectPublish is called)
}
@Override
public void onUserOffline() {
//Will be received when the logged in user goes offline(when disconnectPublish is called).
}
@Override
public void onChannelUpdated() {
//When the channel sync call has been completed
}
@Override
public void onConversationRead(String userId, boolean isGroup) {
//If the conversation has been read by a user
//if isGroup is true, the user has read the conversation in a group
}
@Override
public void onUserDetailUpdated(String userId) {
//When the user details have been updated for a user
}
@Override
public void onMessageMetadataUpdated(String keyString) {
//When message metadata is updated
}
@Override
public void onUserMute(boolean mute, String userId) {
//When a user is muted by the logged in user
}
@Override
public void onGroupMute(Integer groupId) {
// When group is mute from same user from differnt device
}
override fun onMessageSent(message: Message?) {
//When a message has been sent
}
override fun onMessageReceived(message: Message?) {
//when a new message is received. You could reload the message list or add this message to the existing message list to update this message on UI.
}
override fun onLoadMore(loadMore: Boolean) {
//If message list pagination has been called
}
override fun onMessageSync(message: Message?, key: String?) {
//If a message has been synced with server.
}
override fun onMessageDeleted(messageKey: String?, userId: String?) {
//If a message was deleted successfully for a user
}
override fun onMessageDelivered(message: Message?, userId: String?) {
//If a message has been delivered to a User with userId
}
override fun onAllMessagesDelivered(userId: String?) {
//If all the pending messages have been delivered with to the User
}
override fun onAllMessagesRead(userId: String?) {
//If all messages have been read by the User
}
override fun onConversationDeleted(userId: String?, channelKey: Int?, response: String?) {
//If a conversation thread has been deleted. If channelKey is not null, it is for the group else it is for the user.
}
override fun onUpdateTypingStatus(userId: String?, isTyping: String?) {
//If the typing status has been updated for the user.
//if isTyping is 1, the user has started typing
//if isTyping is 0, the user has stopped typing
}
override fun onUpdateLastSeen(userId: String?) {
//Will be received if the User's last seen has been updated or if login user blocked some one or blocked by some one to login user
//Will be received if the User's last seen has been updated or if login user blocked some one or blocked by some one to login user
if (userId != null) {
val service = ContactDatabase(this)
val contact = service.getContactById(userId)
if (contact != null) {
Log.i("Blocked", " Is Login user blocked the userID ? :" + contact.userId + "blocked ?" + contact.isBlocked)
Log.i("Blocked BY", " Is Some one blocked the login user ? :" + contact.userId + "blockedBy ?" + contact.isBlockedBy)
}
}
}
override fun onMqttDisconnected() {
//call connectPublish method here
}
override fun onMqttConnected() {
//Will be received when Mqtt connection is successfull
}
override fun onUserOnline() {
//Will be received when the logged in user goes online(when connectPublish is called)
}
override fun onUserOffline() {
//Will be received when the logged in user goes offline(when disconnectPublish is called).
}
override fun onUserActivated(isActivated: Boolean) {
}
override fun onChannelUpdated() {
//When the channel sync call has been completed
}
override fun onConversationRead(userId: String?, isGroup: Boolean) {
//If the conversation has been read by a user
//if isGroup is true, the user has read the conversation in a group
}
override fun onUserDetailUpdated(userId: String?) {
//When the user details have been updated for a user
}
override fun onMessageMetadataUpdated(keyString: String?) {
//When message metadata is updated
}
override fun onUserMute(mute: Boolean, userId: String?) {
//When a user is muted by the logged in user
}
override fun onGroupMute(groupId: Int?) {
// When group is mute from same user from differnt device
}
Unregister the listener
Once the user leaves the chat activity/fragment, the real time update is no longer needed. You can unregister the listener at that point using the unique id with which it was registered. Use the below code to unregister the ApplozicUIListener
:
AlEventManager.getInstance().unregisterUIListener("listener2");
AlEventManager.getInstance().unregisterUIListener("listener2")
Note
The best place for register would be
onCreate()
, and for unregister, it would beonDestroy()
.This will ensure you get the updates even if your activity/fragment is in background. You can register as many instances of the listener as you want with unique ids.
Sending Typing status
The user can publish his/her typing status to any one who has subscribed for the same. You can publish your typing status using the below code :
Applozic.publishTypingStatus(context, channel, contact, isTypingStarted);
Applozic.publishTypingStatus(context, channel, contact, isTypingStarted)
Argument | Type | Description |
---|---|---|
context | Context/Activity | The calling context |
channel | Channel | Publishing your typing status to a particular channel |
contact | Contact | Publishing your typing status to a particular User |
isTypingStarted | boolean | true if typing has started |
Call the above method in the onTextChangedListener()
call back of the TextWatcher
attached to the EditText
.
Subscribing to typing status
You need to subscribe to a users typing status to get notified for the same. Use the below code to subscribe for the typing status for a user or in a group.
Applozic.subscribeToTyping(Context context, Channel channel, Contact contact);
Applozic.subscribeToTyping(context, channel, contact)
Argument | Type | Description |
---|---|---|
context | Context/Activity | The calling context |
channel | Channel | The Group to which the user wants to subscribe. Should be null if it is for 1-to-chat. |
contact | Contact | The user to whose typing status you want to subscribe to |
UnSubscribe for typing status
If you have subscribed for a user's typing status, you need to unsubscribe for the same too. Use the below code to un-subscribe for a user's typing status:
Applozic.unSubscribeToTyping(Context context, Channel channel, Contact contact);
Applozic.unSubscribeToTyping(context, channel, contact)
Updating the user status
When a user calls the connectPublish
method, he/she will be marked as online in applozic platform until a call to disconnectPublish
method has been made. Whenever the status changes the callback
onUpdateLastSeen(String userId)
from ApplozicUIListener
(If registered) will be fired. The Contact would be automatically updated in the local DB irrespective of if the callback is registered or not. But you would need the callback to update the status on the UI in real time.
For e.g If you have a chat thread opened with a Contact mUser and ApplozicUIListener is registered in the fragment/activity. Whenever the status of mUser changes the callback will be fired and you need to update the contact in the fragment/activity as below:
@Override
public void onUpdateLastSeen(String userId) {
//to avoid update if chat thread is opened with different contact or group
if(userId != null && mUser != null && userId.equals(mUser.getUserId())) {
//we have updated the current contact
mUser = appContactService.getContactById(userId);
processLastSeenStatus(mUser);
}
override fun onUpdateLastSeen(userId: String?) {
//to avoid update if chat thread is opened with different contact or group
if (mUser != null && userId.equals(mUser.getUserId())) {
//we have updated the current contact
mUser = contact.getContactById(userId)
processLastSeenStatus(mUser)
}
}
Your logic to display the status goes inside the method processLastSeenStatus()
public void processLastSeenStatus(Contact contact){
if(contact.isBlocked() || contact.isBlockedBy() || contact.isDeleted()){
statusTv.setText("");
return;
}
if(contact.isConnected()){
statusTv.setText("Online");
}else if(contact.getLastSeenAt() != 0){
//Use formate from applozic as below or create your own format from contact.getLastSeenAt()
statusTv.setText(getContext().getString(R.string.subtitle_last_seen_at_time) + " " + DateUtils.getDateAndTimeForLastSeen(getContext(), contact.getLastSeenAt(), R.string.JUST_NOW, R.plurals.MINUTES_AGO, R.plurals.HOURS_AGO, R.string.YESTERDAY));
}else {
statusTv.setText("");
}
}
fun processLastSeenStatus(contact: Contact) {
if (contact.isBlocked || contact.isBlockedBy || contact.isDeleted) {
statusTv.setText("")
return
}
if (contact.isConnected) {
statusTv.setText("Online")
} else if (contact.lastSeenAt != 0L) {
//Use formate from applozic as below or create your own format from contact.getLastSeenAt()
statusTv.setText(getContext().getString(R.string.subtitle_last_seen_at_time).toString() + " " + DateUtils.getDateAndTimeForLastSeen(getContext(), contact.lastSeenAt, R.string.JUST_NOW, R.plurals.MINUTES_AGO, R.plurals.HOURS_AGO, R.string.YESTERDAY))
} else {
statusTv.setText("")
}
}
Updated 10 months ago