I am on last Steps of my Chat app, i'm trying to receive Notification whenever Messages are Delivered, so i found this implementation:
MessageEventRequestListener
which comes with 4 overrides:
#Override
public void deliveredNotificationRequested(String from, String packetID,
MessageEventManager messageEventManager) {
System.out.println("delievered");
}
#Override
public void displayedNotificationRequested(String from, String packetID,
MessageEventManager messageEventManager) {
System.out.println("displaydelievered");
}
#Override
public void composingNotificationRequested(String from, String packetID,
MessageEventManager messageEventManager) {
System.out.println("composingdelievered");
}
#Override
public void offlineNotificationRequested(String from, String packetID,
MessageEventManager messageEventManager) {
System.out.println("offlinedelievered");
}
but when a message is sent, nothing happened, i'm wondering am i missing any thing? is this the right approach ? thanks
As #Flow said,XEP-22: Message events is deprecated.You can use DeliveryReceiptManager.
The listener invoked when message received at receiver side
DeliveryReceiptManager.getInstanceFor(connection).addReceiptReceivedListener(new ReceiptReceivedListener()
{
#Override
public void onReceiptReceived(String arg0, String arg1, String arg2) {
Log.i("Message Delivered To=", arg0 + ", From = " + arg1 + " , ID= " + arg2);
}
});
}
while sending message add following code
//add delivery receipt request
DeliveryReceiptManager.addDeliveryReceiptRequest(Message);
In PacketListener add following code
Packet received = new Message();
received.addExtension(new DeliveryReceipt(packet.getPacketID()));
received.setTo(packet.getFrom());
connection.sendPacket(received);
XEP-22: Message events is deprecated, I don't recommend using it. Use Delivery Receipts (XEP-0184) instead: https://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.html
First add these to your configuration-
DeliveryReceiptManager.setDefaultAutoReceiptMode(DeliveryReceiptManager.AutoReceiptMode.always);
ProviderManager.addExtensionProvider(DeliveryReceipt.ELEMENT, DeliveryReceipt.NAMESPACE, new DeliveryReceipt.Provider());
ProviderManager.addExtensionProvider(DeliveryReceiptRequest.ELEMENT, DeliveryReceipt.NAMESPACE, new DeliveryReceiptRequest.Provider());
Then after XMPPTcpConnection established add these-
DeliveryReceiptManager deliveryReceiptManager = DeliveryReceiptManager.getInstanceFor(this.connection);
deliveryReceiptManager.setAutoReceiptMode(DeliveryReceiptManager.AutoReceiptMode.always);
deliveryReceiptManager.autoAddDeliveryReceiptRequests();
This will enable delivery receipt for all messages.
SENT:
<iq to='chat_host' id='o2huU-440' type='get'><query xmlns='http://jabber.org/protocol/disco#info'></query></iq>
RECV:
<iq from='chat_host'id='o2huU-440' to='userJID'type='result'><query xmlns='http://jabber.org/protocol/disco#info'> <feature var='urn:xmpp:receipts'/></query>
For auto receipt mode all message will be sent with a receipt request extension. And you will get delivery receipt for all messages.
For each message you send, you may send notifications requests with :
MessageEventManager.addNotificationsRequests(message,
true, true, true, true);
use this code where you get packet of message.
//checking is deliverd or not.
if(msg.getBody().toString().equalsIgnoreCase("RecivedByReciver")){
//do what you want after get notify.
}else{
//do what you want if not delevery report message.
Message message=new Message(ConnectionManager.parseBareAddress(msg.getFrom()),Message.Type.chat);
message.addBody(null,"RecivedByReciver");
Connection().sendPacket(message);
}
Related
sorry for my bad english.
I sending push notification from my codeigniter web to android app, I have 3 devices to test it.
My first device, it works well for me.
And then in my second and third device my android didn't receive any message.
I tried to send notification from my firebase console, then I choose target is user segment with my package name. All of my devices receive the message.
Then I tried to send notification using topic, which is my topic is global. Only my first device receives the message.
Here's my code :
public static final String TOPIC_GLOBAL = "global";
public static final String REGISTRATION_COMPLETE = "registrationComplete";
public static final String PUSH_NOTIFICATION = "pushNotification";
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// checking for type intent filter
if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) {
// gcm successfully registered
// now subscribe to `global` topic to receive app wide notifications
FirebaseMessaging.getInstance().subscribeToTopic(Config.TOPIC_GLOBAL);
displayFirebaseRegId();
} else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) {
// new push notification is received
String message = intent.getStringExtra("message");
Toast.makeText(getApplicationContext(), "Push notification: " + message, Toast.LENGTH_LONG).show();
// txtMessage.setText(message);
}
}
};
private void displayFirebaseRegId() {
SharedPreferences pref = getApplicationContext().getSharedPreferences(Config.SHARED_PREF, 0);
String regId = pref.getString("regId", null);
Log.e(TAG, "Firebase reg id: " + regId);
if (!TextUtils.isEmpty(regId))
{
//Toast.makeText(getApplicationContext(),regId,Toast.LENGTH_LONG).show();
}
// Toast.makeText(getApplicationContext(), regId, Toast.LENGTH_LONG).show();
else
Toast.makeText(getApplicationContext(),"Firebase Reg Id is not received yet!)",Toast.LENGTH_LONG).show();
}
This is my code and i am sending my message in this method but not able to get delivery message in DeliveryReceipt
newChat.sendMessage(message);
newChat.getListeners();
newChat.addMessageListener(new ChatMessageListener() {
#Override
public void processMessage(Chat chat, Message message) {
Log.d(TAG,"DeliveryReceipt3:"+"1:"+message.getThread()+"2:"+chat.getThreadID()+"3:"+message.getBody());
}
});
the above code is for sending message and below code is for getting DeliveryReceipt
Message m = new Message();
m.setType(Message.Type.chat);
m.setFrom(connection.getUser());
m.setTo(agentId);
m.addExtension(new DeliveryReceipt(m.getPacketID()));
DeliveryReceipt dr = (DeliveryReceipt)m.getExtension(DeliveryReceipt.ELEMENT, DeliveryReceipt.NAMESPACE);
Log.d(TAG,"DeliveryReceipt1: "+"1:"+dr.getElementName()+"2:"+dr.getId()+"3:"+dr.getNamespace()+"4:"+dr.toXML()+"4:"+dr.toString());
Log.d(TAG,"DeliveryReceipt2: "+"1:"+m.getBody()+"2:"+m.getStanzaId()+"3:"+m.getThread());
you need to add DeliveryReceiptManager after you successfully logs in
DeliveryReceiptManager dm = DeliveryReceiptManager.getInstanceFor(connection);
dm.setAutoReceiptMode(AutoReceiptMode.always);
dm.autoAddDeliveryReceiptRequests();
dm.addReceiptReceivedListener(new ReceiptReceivedListener() {
#Override
public void onReceiptReceived(Jid fromJid, Jid toJid,
final String receiptId, Stanza receipt) {
// handle delivery receipt here
}
});
First add these to your configuration-
DeliveryReceiptManager.setDefaultAutoReceiptMode(DeliveryReceiptManager.AutoReceiptMode.always);
ProviderManager.addExtensionProvider(DeliveryReceipt.ELEMENT, DeliveryReceipt.NAMESPACE, new DeliveryReceipt.Provider());
ProviderManager.addExtensionProvider(DeliveryReceiptRequest.ELEMENT, DeliveryReceipt.NAMESPACE, new DeliveryReceiptRequest.Provider());
Then after XMPPTcpConnection established add these-
DeliveryReceiptManager deliveryReceiptManager = DeliveryReceiptManager.getInstanceFor(this.connection);
deliveryReceiptManager.setAutoReceiptMode(DeliveryReceiptManager.AutoReceiptMode.always);
deliveryReceiptManager.autoAddDeliveryReceiptRequests();
This will enable delivery receipt for all messages.
SENT:
<iq to='chat_host' id='o2huU-440' type='get'><query xmlns='http://jabber.org/protocol/disco#info'></query></iq>
RECV:
<iq from='chat_host'id='o2huU-440' to='userJID'type='result'><query xmlns='http://jabber.org/protocol/disco#info'> <feature var='urn:xmpp:receipts'/></query>
For auto receipt mode all message will be sent with a receipt request extension. And you will get delivery receipt for all messages.
In Quickblox GCM, when i try to send a message via push to a certain user id, i receive the notification on the sender's device too. I am not sure why, is it the norm in development mode?
QBEvent event = new QBEvent();
event.setUserId(sendToUserId);
event.setType(QBEventType.ONE_SHOT);
event.setEnvironment(QBEnvironment.DEVELOPMENT);
event.setNotificationType(QBNotificationType.PUSH);
event.setPushType(QBPushType.GCM);
HashMap<String, String> data = new HashMap<String, String>();
data.put("data.message", "Message from John");
data.put("data.type", "Notify");
data.put("ParentId",dialogId.toString());
event.setMessage(data);
QBMessages.createEvent(event, new QBEntityCallbackImpl<QBEvent>() {
#Override
public void onSuccess(QBEvent qbEvent, Bundle args) {
System.out.println("GCM Message Sent inside event " );
}
#Override
public void onError(List<String> errors) {
System.out.println("GCM Message ERROR inside event ");
}
});
The above code does send a GCM, but to both devices. The sendToUserId as well as the sender's device.
Am i doing anything wrong?
Actually you don't need to set the user_id field - it comes in a response from server and contains the ID of a sender
Look at Push code sample http://quickblox.com/developers/SimpleSample-messages_users-android#Send_Push_Notifications_from_Application
// recipients
StringifyArrayList<Integer> userIds = new StringifyArrayList<Integer>();
userIds.add(53779);
userIds.add(960);
QBEvent event = new QBEvent();
event.setUserIds(userIds);
So, it should be userIds, not userId
I am confused while implementing the upstream message using the new GoogleCloudMessaging APIs :
public void onClick(final View view) {
if (view == findViewById(R.id.send)) {
new AsyncTask() {
#Override
protected String doInBackground(Void... params) {
String msg = "";
try {
Bundle data = new Bundle();
data.putString("hello", "World");
String id = Integer.toString(msgId.incrementAndGet());
gcm.send(SENDER_ID + "#gcm.googleapis.com", id, data);
msg = "Sent message";
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
return msg;
}
#Override
protected void onPostExecute(String msg) {
mDisplay.append(msg + "\n");
}
}.execute(null, null, null);
} else if (view == findViewById(R.id.clear)) {
mDisplay.setText("");
}
}
We send the messages(XMPP) to GCM server using the SENDER_ID id, so how can my third party server identify my device only with the SENDER_ID?
gcm.send(SENDER_ID + "#gcm.googleapis.com", id, data);
The code you posted sends a message from your device to your 3rd server, not to another device. Your server should establish a connection with the Cloud Connection Server, and since establishing that connection requires using SENDER_ID + "#gcm.googleapis.com" for user name, the GCM server can identify your 3rd party server.
When you 3rd party server sends a message to your device, it uses the Registration ID, which identifies your app on a specific device.
EDIT :
I may have misunderstood your question. If you are asking how does the 3rd party server know which device sent the upstream message to it, the message that your 3rd party server receives contains the Registration ID of the sender, as you can see here :
<message id="">
<gcm xmlns="google:mobile:data">
{
"category":"com.example.yourapp", // to know which app sent it
"data":
{
"hello":"world",
},
"message_id":"m-123",
"from":"REGID"
}
</gcm>
</message>
Even though you don't specify the Registration ID when you call gcm.send(...), GCM knows which device sent the message, so (assuming your app registered to GCM and therefore has a Registration ID) they can add the Registration ID to the message (I'm not sure if they add it on the client side before connecting the GCM server, or if the add it at the GCM server, but it doesn't really matter).
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