I am making app where users can chat with each other in app , but the problem is when user send message it doesn't appear in chat box until user refresh the activity . how can i update chat without refresh ?
this is my code
ParseQuery<Message> parseQuery = ParseQuery.getQuery(Message.class);
subscriptionHandling = parseLiveQueryClient.subscribe(parseQuery);
subscriptionHandling.handleEvent(SubscriptionHandling.Event.CREATE, new SubscriptionHandling.HandleEventCallback<Message>() {
#Override
public void onEvent(ParseQuery<Message> query, final Message message) {
// HANDLING create event
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
mList.add(message);
msgAdapter.notifyDataSetChanged();
show_message.scrollToPosition(mList.size() - 1);
}
});
public void onEvent(ParseQuery<Message> query, Message message) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
mList.clear();
getData();
}
});
public void onClick(View v) {
Message msg = parseMessenger.SendMessage(send_txt.getText().toString(), null, new SaveCallback() {
#Override
public void done(ParseException e) {
send_txt.setText("");
}
}, new SendCallback() {
#Override
public void done(ParseException e) {
}
});
if (mList == null) {
mList = new ArrayList<Message>();
}
}
});
getData();
private void getData() {
ParseQuery<Message> messageFromQuery = Message.getAllMessage();
messageFromQuery.whereEqualTo(Message.COL_USER_FROM, userFrom);
messageFromQuery.whereEqualTo(Message.COL_USER_TO, userTo);
ParseQuery<Message> messageToQuery = Message.getAllMessage();
messageToQuery.whereEqualTo(Message.COL_USER_TO, userFrom);
messageToQuery.whereEqualTo(Message.COL_USER_FROM, userTo);
List<ParseQuery<Message>> messageQueries = new ArrayList<ParseQuery<Message>>();
messageQueries.add(messageFromQuery);
messageQueries.add(messageToQuery);
ParseQuery<Message> messageQuery = ParseQuery.or(messageQueries);
messageQuery.orderByAscending("createdAt");
messageQuery.findInBackground(new FindCallback<Message>() {
#Override
public void done(List<Message> messages, ParseException e) {
if (messages != null) {
mList.clear();
mList.addAll(messages);
msgAdapter = new MsgAdapter(requireContext(), mList, userTo.getObjectId(), userTo);
show_message.setAdapter(msgAdapter);
show_message.scrollToPosition(mList.size() - 1);
}
}
});
}
i can add auto refresh when send button is clicked but i don't want so , it will not look nice when users use it .. please help
Related
In my App i have added Observable method in menuitemclicked but it's working when i'm clicking it twice . on Single press. method is not working but button is working fine any suggestion for this or any changes in method .
case R.id.upload:
fetch()
break;
io.reactivex.Observable fetchObservable() {
return io.reactivex.Observable.create(new ObservableOnSubscribe<Data>() {
#Override
public void subscribe(ObservableEmitter<Data> emitter) throws Exception {
try {
final Cursor cursor = getActivity().getContentResolver().query(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{"display_name", "data1"}, null, null, null);
// final Map contact =new HashMap();
while (cursor.moveToNext()) {
Data data = new Data();
try {
String name = cursor.getString(cursor.getColumnIndex(Display_name));
String number = cursor.getString(cursor.getColumnIndex(Data1));
data.setContact_name(name);
data.setNumber(number);
Thread.sleep(60);
emitter.onNext(data);
} catch (Exception e) {
Toast.makeText(context, "not insert , Toast.LENGTH_SHORT).show();
}
}
emitter.onComplete();
}catch (Exception e){
emitter.onError(e);
}
}
});
// fetching method code
void fetch(){
fetchObservable().subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onNext(Data data) {
data.Contact_name=data.getContact_name();
data.number=data.getNumber();
String name= data.Contact_name;
String number= data.number;
}
count++;
textprogress.setText(String.valueOf(count));
}
}
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
});
}
Because u are not Running your UI in main thread
like this
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
textprogress.setVisibility(View.VISIBLE);
textprogress.setVisibility(View.VISIBLE);
}
});
I'm new to android and I tried to create a chat app using Smack 4.1 and Ejabberd.
I have implemented a group chat using MultiUserChat. I have added Messagelistener to listen every new incoming message and add into adapter.
When I enter into chat room and start chat list works very well.
But the problem is when I back to the any other intent and then go back into chat room then when someone messages me, it is received multiple times.
Maybe I set messagelistner multiple times.
Here is my code Activity Class -
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatiing);
user2 = getIntent().getExtras().getString("JID");
msg_edittext = (EditText)findViewById(R.id.messageEditText);
msgListView = (ListView)findViewById(R.id.msgListView);
msgListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
chatlist = new ArrayList<ChatMessage>();
chatlist.clear();
chatAdapter = new ChatAdapter(ChattingGroup.this,chatlist);
msgListView.setAdapter(chatAdapter);
autoJoinRoom(user1,room_name,new View(getApplicationContext()));
ImageButton sendButton = (ImageButton)findViewById(R.id.sendMessageButton);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendTextMessage(view);
}
});
}
public void autoJoinRoom(String user, String room, View view){
LoginActivity activity = new LoginActivity();
XMPPTCPConnection connection = activity.getmService().xmpp.connection;
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
MultiUserChat multiUserChat = manager.getMultiUserChat(room);
try {
multiUserChat.join(user,"12345");
chatlist.clear();
multiUserChat.addMessageListener(new MessageListener() {
#Override
public void processMessage(Message message) {
if(message.getBody() != null){
Log.d("New Message Received",message.getBody());
chatlist.add(message.getBody());
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
/* Change adapter */
((BaseAdapter) msgListView.getAdapter()).notifyDataSetChanged();
}
});
}
}
});
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
}
}
How can I solve this problem ?
I am not able to get the user online/offline status in QuickBlox. I have tried using QBRoster.
The function that I have written to get user presence.
private void subscribeUserForStatus(ArrayList<Integer> mQBUserList) {
if (QBChatService.getInstance().getRoster() != null) {
mQbRoster = QBChatService.getInstance().getRoster(
QBRoster.SubscriptionMode.mutual, this);
mQbRoster.addRosterListener(this);
for (Integer mId : mQBUserList) {
try {
if (mQbRoster.contains(mId)) {
mQbRoster.subscribe(mId);
} else {
mQbRoster.createEntry(mId, null);
}
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
Log.e("Crash on subscription", e.getMessage());
}
}
}
}
int userID = 45;
QBPresence presence = chatRoster.getPresence(userID);
if (presence == null) {
// No user in your roster
return;
}
if (presence.getType() == QBPresence.Type.online) {
// User is online
}else{
// User is offline
}
This can also help you :
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 presence) {
}
};
This link is helpful :
https://quickblox.com/developers/Android_XMPP_Chat_Sample
The above answer is correct and you can use it like this
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 presence) {
if (presence == null) {
// No user in your roster
return;
}
if (presence.getType() == QBPresence.Type.online) {
// User is online
}else{
// User is offline
}
}
};
You can use this code
Roster roster = xmppConnection.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
Presence presence;
for(RosterEntry entry : entries) {
presence = roster.getPresence(entry.getUser());
System.out.println(entry.getUser());
System.out.println(presence.getType().name());
System.out.println(presence.getStatus());
}
Hi I am developing an android chat application using parse as back end and sinch service.
Everything is working fine like sending and receiving messages between two android devices.I am also using push notification from parse.com.
Now i want to modify the applications like when the new message arrives it must show that the message is pending in my chat application same as that
Whats-App
Here is my code
ListUserActivity.java
private void setConversationsList() {
currentUserId = ParseUser.getCurrentUser().getObjectId();
names = new ArrayList<String>();
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereNotEqualTo("objectId", currentUserId);
query.findInBackground(new FindCallback<ParseUser>() {
public void done(List<ParseUser> userList, com.parse.ParseException e) {
if (e == null) {
for (int i=0; i<userList.size(); i++) {
names.add(userList.get(i).getUsername().toString());
}
usersListView = (ListView)findViewById(R.id.usersListView);
namesArrayAdapter =
new ArrayAdapter<String>(getApplicationContext(),
R.layout.user_list_item, names);
usersListView.setAdapter(namesArrayAdapter);
usersListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int i, long l) {
try {
System.out.println(i);
openConversation(names, i);
}
catch (IndexOutOfBoundsException e1){
System.out.println(e1.getMessage());
}
}
});
} else {
Toast.makeText(getApplicationContext(),
"Error loading user list",
Toast.LENGTH_LONG).show();
}
}
});
}
MessagingActivity.java
public class MessagingActivity extends ActionBarActivity {
private String recipientId;
private String name;
private EditText messageBodyField;
private String messageBody;
private MessageService.MessageServiceInterface messageService;
private MessageAdapter messageAdapter;
private ListView messagesList;
private String currentUserId;
private ServiceConnection serviceConnection = new MyServiceConnection();
private MessageClientListener messageClientListener = new MyMessageClientListener();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.messaging);
bindService(new Intent(this, MessageService.class), serviceConnection, BIND_AUTO_CREATE);
Intent intent = getIntent();
recipientId = intent.getStringExtra("RECIPIENT_ID");
name=intent.getStringExtra("name");
setTitle(name);
currentUserId = ParseUser.getCurrentUser().getObjectId();
// Store app language and version
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
installation.put("userI", currentUserId);
installation.saveInBackground();
messagesList = (ListView) findViewById(R.id.listMessages);
messageAdapter = new MessageAdapter(this);
messagesList.setAdapter(messageAdapter);
populateMessageHistory();
messageBodyField = (EditText) findViewById(R.id.messageBodyField);
findViewById(R.id.sendButton).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendMessage();
}
});
}
//get previous messages from parse & display
private void populateMessageHistory() {
String[] userIds = {currentUserId, recipientId};
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseMessage") ;
query.whereContainedIn("senderId", Arrays.asList(userIds));
query.whereContainedIn("recipientId", Arrays.asList(userIds));
query.orderByAscending("createdAt");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> messageList, com.parse.ParseException e) {
if (e == null) {
for (int i = 0; i < messageList.size(); i++) {
WritableMessage message = new WritableMessage(messageList.get(i).get("recipientId").toString(), messageList.get(i).get("messageText").toString());
if (messageList.get(i).get("senderId").toString().equals(currentUserId)) {
messageAdapter.addMessage(message, MessageAdapter.DIRECTION_OUTGOING);
} else {
messageAdapter.addMessage(message, MessageAdapter.DIRECTION_INCOMING);
}
}
}
}
});
}
private void sendMessage() {
messageBody = messageBodyField.getText().toString();
if (messageBody.isEmpty()) {
Toast.makeText(this, "Please enter a message", Toast.LENGTH_LONG).show();
return;
}
messageService.sendMessage(recipientId, messageBody);
messageBodyField.setText("");
}
#Override
public void onDestroy() {
messageService.removeMessageClientListener(messageClientListener);
unbindService(serviceConnection);
super.onDestroy();
}
private class MyServiceConnection implements ServiceConnection {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
messageService = (MessageService.MessageServiceInterface) iBinder;
messageService.addMessageClientListener(messageClientListener);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
messageService = null;
}
}
private class MyMessageClientListener implements MessageClientListener {
#Override
public void onMessageFailed(MessageClient client, Message message,
MessageFailureInfo failureInfo) {
Toast.makeText(MessagingActivity.this, "Message failed to send.", Toast.LENGTH_LONG).show();
}
#Override
public void onIncomingMessage(MessageClient client, Message message) {
if (message.getSenderId().equals(recipientId)) {
// Toast.makeText(getApplicationContext(),"message",Toast.LENGTH_SHORT).show();
WritableMessage writableMessage = new WritableMessage(message.getRecipientIds().get(0), message.getTextBody());
messageAdapter.addMessage(writableMessage, MessageAdapter.DIRECTION_INCOMING);
}
}
#Override
public void onMessageSent(MessageClient client, Message message, final String recipientId) {
final WritableMessage writableMessage = new WritableMessage(message.getRecipientIds().get(0), message.getTextBody());
messageAdapter.addMessage(writableMessage, MessageAdapter.DIRECTION_OUTGOING);
//only add message to parse database if it doesn't already exist there
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseMessage");
query.whereEqualTo("sinchId", message.getMessageId());
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> messageList, com.parse.ParseException e) {
if (e == null) {
if (messageList.size() == 0) {
ParseObject parseMessage = new ParseObject("ParseMessage");
parseMessage.put("senderId", currentUserId);
parseMessage.put("recipientId", writableMessage.getRecipientIds().get(0));
parseMessage.put("messageText", writableMessage.getTextBody());
parseMessage.put("sinchId", writableMessage.getMessageId());
parseMessage.put("read",false);
parseMessage.saveInBackground();
// messageAdapter.addMessage(writableMessage, MessageAdapter.DIRECTION_OUTGOING);
ParseUser user = ParseUser.getCurrentUser();
String name = user.getUsername();
// Create our Installation query
ParseQuery pushQuery = ParseInstallation.getQuery();
pushQuery.whereEqualTo("userI", writableMessage.getRecipientIds().get(0));
// Send push notification to query
ParsePush push = new ParsePush();
push.setQuery(pushQuery); // Set our Installation query
push.setMessage("Message from"+ name +writableMessage.getTextBody());
push.sendInBackground();
}
}
}
});
}
#Override
public void onMessageDelivered(MessageClient client, MessageDeliveryInfo deliveryInfo) {
Toast.makeText(getApplicationContext(),"delivered",Toast.LENGTH_SHORT).show();
}
#Override
public void onShouldSendPushData(MessageClient client, Message message, List<PushPair> pushPairs) {}
}
}
You can add a new column to your database that keeps track if the conversation has unread messages. Whenever a new message arrives you mark the conversation as unread or pending by setting this column to true.
When you build the list, make your adapter check this column and update the generated listview if the conversation has unread messages.
When the user opens the conversation, update the column to false.
First I suggest you use a ListView with a CursorLoader:
http://developer.android.com/guide/topics/ui/layout/listview.html
Whenever your content provider changes, your adapter will be notified. When it is looping through the cursor building each list item View, you check the desired column. If it is set, you set whatever you like on that View to indicate it is unread.
I am trying to retrieve a row in my table on parse. I found the objectId, but when I try to update the row with new information, nothing happens. Any help would be appreciated. Thanks!
mSaveAndNextSteps.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ParseQuery<SingleFactInfo> query = ParseQuery.getQuery("Fact_Info");
query.getInBackground(mEventObjectId, new GetCallback<SingleFactInfo>() {
public void done(ParseObject fact, ParseException e) {
if (e == null) {
// Now let's update it with some new data. In this case, only cheatMode and score
// will get sent to the Parse Cloud. playerName hasn't changed.
fact.add("factDescriptiontwo", mEventDescription.getText().toString());
event.put("factDescription", mEventDescription.getText().toString());
event.saveInBackground(new SaveCallback() {
#Override
public void done(com.parse.ParseException e) {
}
});
}
}
#Override
public void done(SingleFactInfo parseObject, com.parse.ParseException e) {
Intent goToFactLists = new Intent(CreateEventSectionTwo.this, EventList.class);
startActivity(goToFactLists);
}
});
}
});
So here is the working solution that worked for me. Queried the object using objectId, then updated it in the 'done' section.
mSaveAndNextSteps.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ParseQuery<SingleFactInfo> query = new ParseQuery("Event_Info");
query.getInBackground(mEventObjectId, new GetCallback<SingleFactInfo>() {
public void done(ParseObject event, ParseException e) {
if (e == null) {
// Now let's update it with some new data. In this case, only cheatMode and score
// will get sent to the Parse Cloud. playerName hasn't changed.
Toast.makeText(getApplicationContext(), mYourEditText.getText().toString(), Toast.LENGTH_LONG).show();
}
}
#Override
public void done(SingleFactInfo parseObject, com.parse.ParseException e) {
parseObject.put("eventDescription", mYourEditText.getText().toString());
parseObject.saveInBackground();
Intent goToFactsList = new Intent(YourApplication.this, EventList.class);
startActivity(goToFactsList);
}
});
}
});