Receiving Xmpp message, Attribute missing - android

I am developing small chat application using xmpp and ASMACK android-8-4.0.6 .On sending message, server sends me reply to acknowledge that message has successfully reached the server. and reply looks like as follows
<message to="abc#ofsrv1"><a xmlns="urn:xmpp:sm:3" h="6vO1d-7"/></message>
where attribute 'h' inside element contains packet id of sent message. I am sending message as follows
public void sendMessage(String to, String messageData)
{
try
{
Message msg = new Message(to, Message.Type.chat);
addMessageToLocalDb(to, messageData, msg.getPacketID());
msg.setBody(messageData);
DeliveryReceiptManager.addDeliveryReceiptRequest(msg);
xmppConnection.sendPacket(msg);
} catch (Exception e)
{
}
}
I have attach packet listener in which i am receiving server's reply but it receives in the form as follow
<message to='sender#ofsrv1'><a xmlns='urn:xmpp:sm:3'></a></message>
where 'h' attribute in element is clearly missing. Interesting part is some where in my log cat, under "SMACK" tag i received perfect reply along with h attribute just as follows
<message to="sender#ofsrv1"><a xmlns="urn:xmpp:sm:3" h="6vO1d-7"/></message>
so servers reply is successfully reaching to android client but some how attached packet listener is not receiving it . code for attaching packet listener is
public void configureConnection()
{
try
{
//PacketFilter filter1 = new IQTypeFilter(IQ.Type.RESULT);
PacketFilter filter = new PacketFilter()
{
#Override
public boolean accept(Packet packet)
{
return true;
}
};
XmppPacketListener xmppPacketListener = new XmppPacketListener(this, xmppConnection);
xmppConnection.addPacketListener(xmppPacketListener, filter);
//Registering Delivery receipt Listener
deliveryReceiptManager = DeliveryReceiptManager.getInstanceFor(xmppConnection);
XmppReceiptReceivedListener receiptReceivedListener = new XmppReceiptReceivedListener();
deliveryReceiptManager.addReceiptReceivedListener(receiptReceivedListener);
//Enabling carbons
CarbonManager carbonManager = CarbonManager.getInstanceFor(xmppConnection);
if (carbonManager.isSupportedByServer())
{
carbonManager.sendCarbonsEnabled(true);
}
} catch (Exception e)
{
CustomLogger.showLog("Xmpp", "Error in configuring xmpp connection" + e.toString());
}
}
public class XmppPacketListener implements PacketListener
{
private XMPPConnection mXmppConnection;
private Context mContext;
public XmppPacketListener(Context context, XMPPConnection xmppConnection)
{
CustomLogger.showLog(TAG, "Packet listener init");
this.mContext = context;
this.mXmppConnection = xmppConnection;
}
#Override
public void processPacket(Packet packet)
{
try
{
CustomLogger.showLog("Message", "Received packet" + packet);
} catch (Exception e)
{
}
}
}
Can any one help me to figure out what exactly i am missing in receiving packets
any help is greatly appreciated

Related

How can I retrieve data from an Arduino using Android?

I'm building an app in Android to communicate with Arduino via usb.
In Android, I create a button to send data to the Arduino. The Arduino should then respond to this message and send another message to be treated in the function of the same button. The problem is that when I click on the button the app stops.
My Arduino code:
void setup()
{
Serial.begin(9600);
}
void loop()
{
char c;
int i = 0;
if(Serial.available()){
c=Serial.read();
if (c == '4'){
Serial.write("X:100 Y:10");
}
}
}
Defining a Callback which triggers whenever data is read in Android:
UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
#Override
public void onReceivedData(byte[] arg0) {
String data = null;
try {
data = new String(arg0, "UTF-8");
data.concat("\n");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
};
The button function in Android is:
public void goBefore(View view) {
ssend = "M114"; // send message to update current position
serialPort.write(ssend.getBytes());
String[] current_Pos = data.split(" ");
Do you know what I'm doing wrong?

Android: how to change IP Address from within TCP Client app?

I am trying to communicate between a C# TCP server, and an Android TCP client. I am new to android so used the second part of this tutorial to create the android client:
http://www.myandroidsolutions.com/2012/07/20/android-tcp-connection-tutorial/#.V8uZISgrKUk
Everything works fine, and I can send little text messages between my phone and my computer, however this tutorial requires that the client app have the server IP hard coded into the program, and for obvious reasons this is going to cause issues if I actually wanted to make an app that uses this.
Outside of this tutorial I have added a second EditText ("#id/ipTxt") and a second button ("#id/setIp")
As I don't want to make anybody read through the whole tutorial, here are the important parts summarized:
Main Activity:
public class MyActivity extends Activity
{
private ListView mList;
private ArrayList<String> arrayList;
private MyCustomAdapter mAdapter;
private TCPClient mTcpClient;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
arrayList = new ArrayList<String>();
final EditText editText = (EditText) findViewById(R.id.editText);
Button send = (Button)findViewById(R.id.send_button);
//relate the listView from java to the one created in xml
mList = (ListView)findViewById(R.id.list);
mAdapter = new MyCustomAdapter(this, arrayList);
mList.setAdapter(mAdapter);
// connect to the server
new connectTask().execute("");
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String message = editText.getText().toString();
//add the text in the arrayList
arrayList.add("c: " + message);
//sends the message to the server
if (mTcpClient != null) {
mTcpClient.sendMessage(message);
}
//refresh the list
mAdapter.notifyDataSetChanged();
editText.setText("");
}
});
}
public class connectTask extends AsyncTask<String,String,TCPClient> {
#Override
protected TCPClient doInBackground(String... message) {
//we create a TCPClient object and
mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(String message) {
//this method calls the onProgressUpdate
publishProgress(message);
}
});
mTcpClient.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
//in the arrayList we add the messaged received from server
arrayList.add(values[0]);
// notify the adapter that the data set has changed. This means that new message received
// from server was added to the list
mAdapter.notifyDataSetChanged();
}
}
}
TCPClient class:
public class TCPClient {
private String serverMessage;
public static final String SERVERIP = "192.168.0.102"; //your computer IP address
public static final int SERVERPORT = 4444;
private OnMessageReceived mMessageListener = null;
private boolean mRun = false;
PrintWriter out;
BufferedReader in;
/**
* Constructor of the class. OnMessagedReceived listens for the messages received from server
*/
public TCPClient(OnMessageReceived listener) {
mMessageListener = listener;
}
/**
* Sends the message entered by client to the server
* #param message text entered by client
*/
public void sendMessage(String message){
if (out != null && !out.checkError()) {
out.println(message);
out.flush();
}
}
public void stopClient(){
mRun = false;
}
public void run() {
mRun = true;
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVERPORT);
try {
//send the message to the server
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
Log.e("TCP Client", "C: Sent.");
Log.e("TCP Client", "C: Done.");
//receive the message which the server sends back
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//in this while the client listens for the messages sent by the server
while (mRun) {
serverMessage = in.readLine();
if (serverMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(serverMessage);
}
serverMessage = null;
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + serverMessage + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
socket.close();
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
//Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
//class at on asynckTask doInBackground
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
My theory would be to stop the connectTask process every time the "setIp" button is clicked and create a new one, but that seems like a very inefficient way to do it, plus I don't know how I would go about doing that :(
Any Ideas?
Change your SERVERIP and SERVERPORT constants into non-static variables instead, and then initialize them using additional input values to your TCPClient constructor, or as input parameters to AsyncTask.execute() (which will then be passed as input parameters to your doInBackground() method).
Don't call execute() until you have first determined those values, either from your app's stored configuration, or from the user in the UI.
When you do start a new task, save the object to a variable in your main code (which you are not currently doing). To cancel the connection, you can then call the AsyncTask.cancel() method on that variable. Make sure your connectTask.doInBackground() and TCPClient.run() code checks the AsyncTask.isCancelled() method periodically so they can exit as soon as possible when it returns true. This technique is mentioned in the AsyncTask documentation.
After the connectTask object finishes running, you can create a new one with different input values.

XMPP Group Chat Android

I implemented a Group Chat mechanism in my Android where I have created groups and add members through REST API Plugin of Openfire. sending messages to to the same group not delivering messages to all members of the same group. Please see my Error Log for the same, and suggest me any solution regarding the same.
Log:
11-26 17:51:42.364 10035-10035/com.myoneapp.chat V/Cursor data==>>﹕ To User ID==> onCreateLoader=>terehokerahenge
11-26 17:51:47.018 10035-10654/com.myoneapp.chat I/System.out﹕ 05:51:47 PM SENT (0): <message to='terehokerahenge#conference.chat.spectratech.in' id='362-05' type='groupchat'><body>hi</body><SenderName></SenderName><mediaType>0</mediaType><request xmlns='urn:xmpp:receipts'/></message>
11-26 17:51:47.066 10035-10035/com.myoneapp.chat V/ChatWindow﹕ MESSAGE TYPE==>0
11-26 17:51:47.070 10035-10035/com.myoneapp.chat V/ChatWindow﹕ MESSAGE TYPE==>0
11-26 17:51:47.072 10035-10035/com.myoneapp.chat V/ChatWindow﹕ MESSAGE TYPE==>0
11-26 17:51:48.097 10035-10655/com.myoneapp.chat I/System.out﹕ 05:51:48 PM RECV (0): <message to="sanat#chat.spectratech.in/chat.spectratech.in" id="362-05" type="error" from="terehokerahenge#conference.chat.spectratech.in"><body>hi</body><SenderName/><mediaType>0</mediaType><request xmlns="urn:xmpp:receipts"/><error code="406" type="modify"><not-acceptable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></message>
11-26 17:51:48.102 10035-10654/com.myoneapp.chat I/System.out﹕ 05:51:48 PM SENT (0): <message to='terehokerahenge#conference.chat.spectratech.in' id='CGIln-9' type='error'><received xmlns='urn:xmpp:receipts' id='362-05'/></message>
Code:
new Thread(new Runnable() {
#Override
public void run() {
activity.getmService().xmpp.createMUCGroup(etGroupSubject.getText().toString(), mAppPreferences.getUserName());
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
activity.getmService().xmpp.inViteUserstoGroup(jabberids);
}
});
}
}).start();
public void createMUCGroup(String gJID, String owner){
mMultiUserChat = getMUChatManager().getMultiUserChat(gJID + "#conference.chat.spectratech.in");
try {
mMultiUserChat.create(mAppPreferences.getUserName());
// Get the the room's configuration form
// org.jivesoftware.smackx.xdata.Form form = mMultiUserChat.getConfigurationForm();
// Create a new form to submit based on the original form
org.jivesoftware.smackx.xdata.Form form = mMultiUserChat.getConfigurationForm().createAnswerForm();
form.setAnswer("muc#roomconfig_publicroom", true);
form.setAnswer("muc#roomconfig_roomname", gJID);
form.setAnswer("muc#roomconfig_roomowners",gJID);
form.setAnswer("muc#roomconfig_persistentroom", true);
mMultiUserChat.sendConfigurationForm(form);
/*org.jivesoftware.smackx.xdata.Form submitForm = form.createAnswerForm();
// Add default answers to the form to submit
for (java.util.Iterator fields = (java.util.Iterator) form.getFields(); fields.hasNext(); ) {
org.jivesoftware.smackx.xdata.FormField field = (org.jivesoftware.smackx.xdata.FormField) fields.next();
if (!org.jivesoftware.smackx.xdata.FormField.Type.hidden.equals(field.getType()) && field.getVariable() != null) {
// Sets the default value as the answer
submitForm.setDefaultAnswer(field.getVariable());
}
}*/
// Sets the new owner of the room
/*java.util.List owners = new java.util.ArrayList();
owners.add(mAppPreferences.getUserName()+"#chat.spectratech.in");
submitForm.setAnswer("muc#roomconfig_roomowners", owners);
// Send the completed form (with default values) to the server to configure the room
mMultiUserChat.sendConfigurationForm(submitForm);*/
}catch (Exception e){
e.printStackTrace();
}
}
public void inViteUserstoGroup(java.util.ArrayList<String> users){
getMUChatManager().addInvitationListener(MyXMPP.this);
for (int i = 0; i < users.size(); i++) {
try {
mMultiUserChat.invite(users.get(i)+"#chat.spectratech.in", "Meet me in this group.");
} catch (org.jivesoftware.smack.SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
}
#Override
public void invitationReceived(org.jivesoftware.smack.XMPPConnection xmppConnection, org.jivesoftware.smackx.muc.MultiUserChat multiUserChat, String s, String s1, String s2, org.jivesoftware.smack.packet.Message message) {
try {
System.out.println("Invitation Received==========================>");
mMultiUserChat.join(s1);
} catch (org.jivesoftware.smack.SmackException.NoResponseException e) {
e.printStackTrace();
} catch (org.jivesoftware.smack.XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (org.jivesoftware.smack.SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
It returning Error 406, Not acceptable
I think you are missing the implementation of auto accepting Group chat joining Request in your code.
Below code is working for AMACK group chat using Openfire Server
1. Creating XMPP Connection
XMPPTCPConnection connection = new XMPPTCPConnection(config);
connection.connect();
connection.login(ID1, password1);
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
2. Creating Persistant Group Chat Room
MultiUserChat chatRoom = new MultiUserChat(connection, "room786#conference.dishaserver");
chatRoom.create("nagarjuna");
Form form = chatRoom.getConfigurationForm().createAnswerForm();
form.setAnswer("muc#roomconfig_publicroom", true);
form.setAnswer("muc#roomconfig_roomname", "room786");
form.setAnswer("muc#roomconfig_roomowners",owners);
form.setAnswer("muc#roomconfig_persistentroom", true);
chatRoom.sendConfigurationForm(form);
3. Sending invitation to ride participants
MultiUserChat.addInvitationListener(connection, groupChatListener);
chatRoom.invite("surya#dishaserver", "hi surya");
4. Auto accepting the request of RIDER to join group chat
public class GroupChatListener implements InvitationListener{
String nickname;
public GroupChatListener(String nick)
{
nickname = nick;
}
#Override
public void invitationReceived(XMPPConnection con, String room,String inviter, String reason, String password, Message message)
{
System.out.println(" Entered invitation handler... ");
try
{
MultiUserChat chatRoom = new MultiUserChat(con, room);
chatRoom.join(nickname);
}
catch (NoResponseException | XMPPErrorException| NotConnectedException e)
{
e.printStackTrace();
} catch (SmackException e)
{
e.printStackTrace();
}
System.out.println(" Invitation Accepted... ");
}
}
5. Sending message to group chat members
private static void sendMessageToRoomOccupants(XMPPTCPConnection connection) throws NotConnectedException
{
Message msg = new Message("room789#conference.dishaserver",Message.Type.groupchat);
msg.setBody("This is nagarjuna friednds. Please join this room and let us have fun."); connection.sendPacket(msg);
}
6. Receiving the group chat message by ride users
MultiUserChat chatRoom = new MultiUserChat(connection, "room789#conference.dishaserver");
chatRoom.addMessageListener(new GroupChatMsgListener());
package com.disha.test;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.packet.Packet;
public class GroupChatMsgListener implements PacketListener
{
#Override
public void processPacket(Packet packet) throws NotConnectedException
{
System.out.println(" Received group cht messages... ");
System.out.println("from : "+packet.getFrom());
System.out.println("to : "+packet.getTo());
System.out.println(packet.toString());
}
}
In order to send messages in the groupchat you need to join it first:
mMultiUserChat.join("yournickname");
Its not working in 4.1.9 version, you can try this one:
public MultiUserChat mMultiUserChat;
private MultiUserChatManager mMultiUserChatManager;
mMultiUserChatManager = MultiUserChatManager.getInstanceFor(mAbstractXMPPConnection);
mMultiUserChatManager.addInvitationListener(this);
mMultiUserChat = mMultiUserChatManager.getMultiUserChat(room);
mMultiUserChat.addMessageListener(this);
try {
mMultiUserChat.join(yournickname);
// mMultiUserChat.sendConfigurationForm(new Form(DataForm.Type.submit));
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
and for send message:
Message msg = new Message(room, Message.Type.groupchat);
msg.setBody(message);
mMultiUserChat.sendMessage(msg);
Hope this is helpful, thanks.

How to enable the XEP-0199 in Smack?

I'm using aSmack. My app listens a chatroom and reacts to the messages but it never send a message. The app doesn't receive more messages if the chatroom remains in silence for a while and then a new message is sent. I researched and I think that XEP-0199 is the solution here. I see that #Flow (the current Smack maintainer) implemented it and the issue related was closed.
I think that I need to use PingProvider but I really don't know how to connect this class with the Connection.
How can I enable the XEP-0199? How can I use PingProvider?
Connection code:
smack = SmackAndroid.init(getActivity().getApplicationContext());
connection = new XMPPConnection(App.getServer());
connection.addConnectionListener(new ConnectionListener() {
private final static String SMACK = "SMACK";
#Override
public void reconnectionSuccessful() {
Log.i(SMACK , "reconnectionSuccessful");
}
#Override
public void reconnectionFailed(Exception e) {
Log.i(SMACK, "reconnectionFailed", e);
}
#Override
public void reconnectingIn(int seconds) {
Log.i(SMACK, "reconnectingIn " + seconds);
}
#Override
public void connectionClosedOnError(Exception e) {
Log.i(SMACK, "connectionClosedOnError", e);
}
#Override
public void connectionClosed() {
Log.i(SMACK, "connectionClosed");
}
});
connection.connect();
connection.login(user, password);
I fix the problem implementing the ping response manually:
connection.addPacketListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
connection.sendPacket(new Pong((Ping) packet));
}
}, new PacketFilter() {
#Override
public boolean accept(Packet packet) {
return packet instanceof Ping;
}
});
To prevent user from disconnecting your session
PingManager pm = PingManager.getInstanceFor(MyApplication.connection) ;
pm.setPingInterval(5) ; // 5 sec
pm.pingMyServer() ;
pm.registerPingFailedListener(new PingFailedListener() {
#Override
public void pingFailed() {
Log.e(TAG , "pingFailed") ;
}
});
XEP 0199 is not a solution, Ping is used to check weather the server is up or not. actually you will send ping to the server.
Now as fas as your problem is concerned. Show me the message stanza that you are trying to send. and also check if the chat-room is public or private. you can not send a message to a private chat room.
Answer Updated:
Try using this code for detecting message recieve
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
Network.connection.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
Message message = (Message) packet;
if (message.getBody() != null) {
String fromName = StringUtils.parseBareAddress(message.getFrom());
Log.i("XMPPClient", "Got text [" + message.getBody() + "] from [" + fromName + "]");
//recieve.setText(message.getBody());
/*messages.add(fromName + ":");
messages.add(message.getBody());*/
// Add the incoming message to the list view
item = new RowItem(R.drawable.billing, message.getBody());
adapter = new CustomListViewAdapter(getBaseContext(),
R.layout.list_item, rowItems);
rowItems.add(item);
//listView.setAdapter(adapter);
}
}
}, filter);
I called PingManager.getInstanceFor method to enable XEP-0199 support.

Android - Autobahn web socket communication

I am working on Web socket communication with Autobahn library.
The problem I have is after connecting server, then message should be sent without connection again. But the message is sent with different connection that it connects to server every single time to send a message.
public class WebSocket_Connector extends Activity{
private static final String TAG = "ECHOCLIENT";
private static final String TAG1 = "My app";
public final WebSocketConnection mConnection = new WebSocketConnection();
private String tmpString = "";
public void connect(final String wsuri) {
Log.d(TAG, "Connecting to: " + wsuri);
try {
mConnection.connect(wsuri, new WebSocketHandler() {
#Override
public void onOpen() {
Log.d(TAG, "Status: Connected to " + wsuri );
Log.d(TAG, "Connection successful!\n");
mConnection.sendTextMessage(tmpString);
tmpString = "";
}
#Override
public void onTextMessage(String payload) {
Log.d(TAG, "Got echo: " + payload);
}
#Override
public void onClose(int code, String reason) {
Log.d(TAG, "Connection closed.");
}
});
} catch (WebSocketException e) {
Log.d(TAG, e.toString());
}
}
public void sendMessage(String message) {
if (mConnection.isConnected()) {
Log.d(TAG1, "Messeage is sent : " + message);
mConnection.sendTextMessage(message);
}
else {
tmpString = message;
connect("ws://192.168.3.100:7681");
}
}
}
This is the code I have, and...When you see "sendMessage" method, it always goes to 'else' not, if loop. Any suggestion 'experts' please..?
i don't know the package name you are dealing with for websocket. So first it has to be provided to get reliable answer to your question. But let say if it is something similar to :
https://code.google.com/p/weberknecht/source/browse/trunk/src/main/de/roderick/weberknecht/WebSocketConnection.java?r=2
note: i have not seen there isConnected() method but assume that it is added somewhere else.
you can see from source that onOpen() (line 88) is called before connected = true; on line (91). if this member var will be used as result of isConnected() then your code always will follow "else" part of the condition.
i would advice to dig into websocket api and its usage pattern further.

Categories

Resources