I am trying to fetch the chat history using below function:
var mamManager:MamManager= MamManager.getInstanceFor(connection)
var prevMsg=mamManager.queryArchive(JidCreate.entityBareFrom(jid)).forwardedMessages
println(msg.forwardedStanza)
But I am getting the output as
04-19 14:17:58.414 7964-7964/com.example.itstym.smackchat I/System.out: Message Stanza [to=user2#replica3377.cloudapp.net,from=user1#replica3377.cloudapp.net/307135084148417199024926,id=qQ73x-27,]
I can also get stanza id using msg.forwardedStanza.stanzaId but how will i get the msg text.
Cast the forwarded Stanza to Message and call getBody().
The getBody() is for Message and the ForwardedStanza extends Stanza so it can be Message, IQ or Presence.
Try this:
if (forwarded.getForwardedStanza() instanceof Message) {
String body = ((Message) forwarded.getForwardedStanza()).getBody();
}
Related
I'm newby in smack 4.2.4 and xmpp. I've sent bunch of messages but the recipent is not available to get them,I've close the application and next time when I'll open the application want to check the status of messages, which is delivered or not.
You can use XEP-0184: Message Delivery Receipts for check delivery of messages to destination. First you must add the gradle dependency of smack-extensions:
implementation 'org.igniterealtime.smack:smack-extensions:4.2.2;
Then use this code, when you want to send a message, to add receipt request to stanza:
DeliveryReceiptRequest.addTo(message);
Then you can receive the delivery status in a listener like this:
DeliveryReceiptManager d = DeliveryReceiptManager.getInstanceFor(connection);
d.addReceiptReceivedListener(new ReceiptReceivedListener() {
#Override
public void onReceiptReceived(Jid fromJid, Jid toJid, String receiptId, Stanza receipt) {
Log.i("delivery", "for: " + receiptId + " received");
//here you can use sid or receiptId to identify which message is delivered
}
});
Consider that when you are sending message, a random unique stanza-id (sid)
will be setted to your stanza. you must save it in your message row in database, then you can identify that with this sid when receipt received.
I am trying to send custom information with IQ in asmack from android.
So I am using below code to send the custom IQ message.
public void onClick(View arg0) {
CustomIQ req = new CustomIQ();
req.myData="Hello world";
req.setType(IQ.Type.GET);
req.setTo(Activity_title+Constants.DOMAIN);
MainActivity.connection.sendPacket(req);
Log.d(Constants.TAG, "xml value :"+req.toXML());
Log.d(Constants.TAG, "child element value :"+req.getChildElementXML());
Log.d(Constants.TAG, " custom IQ req sent");
Below is my custom IQ class implementation:
import org.jivesoftware.smack.packet.IQ;
public class CustomIQ extends IQ {
String myData;
#Override
public String getChildElementXML() {
String request = "<query xmlns='myxmlns'>"
+ "<myData>"+ myData + "</myData>"
+ "</query>";
return request;
}
}
}
But after the sending the custom IQ, I am getting in the IQ listener as Service Unavailable and error code as 503.
Below are the request to server :
xml value :<iq id="BTn30-5" to="swathi#btp121374" type="get"><query xmlns='myxmlns'><myData>Hello world</myData></query></iq>
child element value :<query xmlns='myxmlns'><myData>Hello world</myData></query>
Below is the response from server:
xml value :<iq id="BTn30-5" to="ganesh#btp121374/Smack" from="swathi#btp121374" type="error"><query xmlns='myxmlns'><myData>Hello world</myData></query><error code="503" type="CANCEL"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>
So what is the reason for I am getting response from server as Service Unavailable.
Edit:
I implemented the IQProvider as below
public class customIQProvider implements IQProvider{
#Override
public IQ parseIQ(XmlPullParser parser) throws Exception {
Log.d(Constants.TAG, "In custom IQ provider");
CustomIQ myIQ_ref = new CustomIQ();
int eventType = parser.next();
while(eventType == XmlPullParser.START_TAG){
switch(parser.getEventType()){
case XmlPullParser.START_TAG:
{
if(parser.getName().equals("myData")){
myIQ_ref.myData=(parser.nextText());
}
}
return myIQ_ref;
}
}
return null;
}
}
I believe you're falling foul of the iq routing rules in XMPP. If you send an iq stanza to "swathi#btp121374", you're not asking it to be routed to a client, you're asking the btp121374 server to handle it on behalf of swathi#btp121374.
Given the resource of the sending JID, I imagine you want to send to "swathi#btp121374/Smack" or similar. Sending it to the full JID (JID including resource) tells the server to route it to the client instead of handling it itself.
(Note that the routing rules for presence, message and iq are different - the above only applies to iq)
Obviously the server doesn't know how to handle your new namespace, unless you also implement it on the server. What do you expect the server to do with your custom element?
Also, it's generally a bad idea to generate XML by concatenating strings. If myData contains and <, or any of the other characters that need to be escaped, your XML will be invalid. Smack surely has better ways to generate your custom data.
I am sending a message with (a)Smack and Openfire server. I am successfully able to send message with the message body. Now i need to send some additional data with the message. I don't want to append the string to the data and then process it after receiving. Is there any other approach? or with extensions?
Use a custom PacketExtension.
You can use setProperty and getProperty method.
At sending end:
Message msg=new Message("jid", Message.Type.chat);
msg.setProperty("key", "value");
connection.sendMessage(msg);
At receiving end:
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
packetListner=new PacketListener() {
public void processPacket(Packet packet) {
Message message = (Message) packet;
String myData=message.getProperty("key").toString();
}
};
connection.addPacketListener(packetListner, filter);
Below is my Android code for group chat:
/* Sends messages */
public void sendChatMessage(String text)
{
Message message = muc.createMessage();
message.setBody(text);
message.setPacketID("ABC_1");
muc.sendMessage(message);
}
/* Listens for messages */
public void receiveMessage()
{
muc.addMessageListener(new PacketListener() {
public void processPacket(Packet packet)
{
final Message message = (Message) packet;
log.i("packed id: ", packet.getPacketID());
log.i("message id: ", message.getPacketID());
}
});
}
The output I see in logcat is:
packet id: null
message id: null
Could you please tell me why the IDs are null? Am I missing something here?
it's OK
Regarding XMPP standart, room doesn't handle message id, so it will be null
Here is an example
sent message to room:
<message to="92_testroom2134#muc.chat.quickblox.com" id="366" type="groupchat"><body>Hello QuickBlox developer!</body></message>
received message from room:
<message xmlns="jabber:client" type="groupchat" from="92_testroom2134#muc.chat.quickblox.com/298" to="298-92#chat.quickblox.com/tigase-19912"><body>Hello QuickBlox developer!</body></message>
no ID in received message
ID only used in 1-1 chat
you can add custom parameters to Messages, just use http://www.igniterealtime.org/builds/smack/docs/3.2.2/javadoc/org/jivesoftware/smack/packet/Packet.html#setProperty(java.lang.String, java.lang.Object) to set
and http://www.igniterealtime.org/builds/smack/docs/3.2.2/javadoc/org/jivesoftware/smack/packet/Packet.html#getProperty(java.lang.String)
to get in listener
I have a Servlet deployed on Google App Engine, which is playing the role of posting broadcast message to GCM. Android clients will receive that broadcast message from GCM. The Servlet extends BaseServlet with following snippet.
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//when receiving a gcm broadcast request, send message to GCM
Builder mb = new Message.Builder();
mb.addData("message", "The message to send");
Message message = mb.build();
sender.sendNoRetry(message, regIds);
...
}
When "the message to send" is in English, all things fine. But if "the message to send" is replaced by other language such as Chinese, the Android client will receive a string of garbled text. On Android client, I use a class extends GCMBaseIntentService to deal with GCM broadcast.
#Override
protected void onMessage(Context context, Intent intent) {
String message = "";
message = intent.getStringExtra("message")!=null ? intent.getStringExtra("message") : "";
doNotify(message);
}
I have tried to re-encode the message but doesn't work.
message = new String(message.getBytes("ISO-8859-1"), "UTF-8");
Have any idea about the problem? I need your help, Thanks.
Try URLEncoder
mb.addData("message", URLEncoder.encode("世界","UTF-8");
another option:
mb.addData("message", new StringEntity("世界", "UTF-8");
After looking at the source code of GCM : com.google.android.gcm.server.Sender , it is useing HttpPost as json, and Java uses UTF-16 to internally so before you post, you will need to encode it properly.
And as comment stated, at client decode the String
String yourAwesomeUnicodeString=URLDecoder.decode(intent.getStringExtra("message"),"UTF-8");