How to close WebSockets properly from Application class? - java

I am using WebSockets for my chat app in android. For convenience, I am creating the connection in Application class so that it can be used by activities and fragments with one instance. Here is the code for my Application class:
public class Main extends Application implements LifecycleObserver {
private static WeakReference<Context> context;
private WebSocket webSocket;
private final Request request;
private final OkHttpClient client;
public static final int SOCKET_CLOSE_CODE = 1000;
#Override
public void onCreate() {
super.onCreate();
context = new WeakReference<>(getApplicationContext());
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
this.client = new OkHttpClient();
this.request = new Request.Builder().url("ws://192.168.1.9:8080").build();
}
public void connect() {
webSocket = client.newWebSocket(request, new WebSocketListener() {
#Override
public void onOpen(WebSocket webSocket, Response response) {
super.onOpen(webSocket, response);
}
#Override
public void onMessage(WebSocket webSocket, String text) {
super.onMessage(webSocket, text);
}
#Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
super.onMessage(webSocket, bytes);
}
#Override
public void onClosing(WebSocket webSocket, int code, String reason) {
super.onClosing(webSocket, code, reason);
}
#Override
public void onClosed(WebSocket webSocket, int code, String reason) {
super.onClosed(webSocket, code, reason);
}
#Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
super.onFailure(webSocket, t, response);
}
});
}
#OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume() {
if (webSocket == null) return;
connect();
}
#OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPause() {
if (webSocket == null) return;
disconnect();
}
private void disconnect() {
webSocket.close(SOCKET_CLOSE_CODE, null);
webSocket = null;
}
#OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onDestroy() {
if (client == null) return;
client.connectionPool().evictAll();
client.dispatcher().executorService().shutdown();
}
}
For some reason, the socket does not close in either onPause or onDestroy (tried both). I am using Ratchet in server side. What's wrong with this code? Note that I want to close the connection exactly from the Application class itself instead of closing from activities or fragments or any other components.

The answer might be WebSocketActivity extends FragmentActivity implements WebSocketListener {} because Activity would implement these lifecycle methods, therefore they can be overridden.

Related

How to run API call inside background runnable and receive response to multiples fragment in java?

i want to call api request every x second using Runnable and read live response to multiple fragment on every api call.
i try bellow code but if start runnable from FragmentA then can't get response on FragmentB even if runnable already run api call in background.
when i run RunnableDemo(mContext, this, JsonRpc.Method.TELL_ACTIVE).run(); in fragmentA and start runnable however can get onDataSuccess in fragmentB.
and if i use RunnableDemo(mContext, this, JsonRpc.Method.TELL_ACTIVE).run(); in FragmentB then run two time API call for FragmentA and FragmentB.
so, how can i run api call every x second once and receive response on multiple fragments?
thank you,
RunnableDemo.java
public class RunnableDemo implements Runnable{
RunnableDemo.RunnableDemoListener listener;
public void run() {
if (myRunnable == null) {
myHandler.postDelayed(myRunnable = new Runnable() {
public void run() {
if(shouldRun) {
running = true;
//do something
loop();
}
myHandler.postDelayed(myRunnable, updateInterval);
}
}, updateInterval);
}
}
private void loop() {
...retrofit....
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(#NonNull Call<ResponseBody> call, #NonNull Response<ResponseBody> response)
{
listener.onDataSuccess(response);
}
#Override
public void onFailure(#NonNull Call<ResponseBody> call, #NonNull Throwable t)
{
listener.onDataError("error");
}
});
}
public void stop() {
if (listener != null) {
listener.onStopped();
}
running = false;
shouldRun = false;
}
public final boolean isRunning() {
return running;
}
public final boolean safeStop() {
if (listener != null) {
listener.onStopped();
}
shouldRun = false;
running = false;
return true;
}
// Listener defined earlier
public interface RunnableDemoListener {
public void onDataError(String title);
public void onDataSuccess(Response<ResponseBody> responseBody);
public void onStopped();
}
}
FragmentA.java
public class FargmentA extends Fragment implements RunnableDemo.RunnableDemoListener{
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
RunnableDemo runnableDemo = new RunnableDemo(mContext, this, JsonRpc.Method.TELL_ACTIVE);
if(!runnableDemo.isRunning()) {
runnableDemo.run();
}
}
#Override
public void onDataError(String title) {
Log.i("TEST", "TestRunnable onResponse receive error Files: "+ title);
}
#Override
public void onDataSuccess(Response<ResponseBody> responseBody) {
Log.i("TEST", "TestRunnable onResponse receive success Files: "+ responseBody.code());
}
#Override
public void onStopped() {
Log.i("TEST", "TestRunnable onResponse receive onStopped Files: ");
}
}
FragmentB.java
public class FargmentB extends Fragment implements RunnableDemo.RunnableDemoListener{
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
RunnableDemo runnableDemo = new RunnableDemo(mContext, this, JsonRpc.Method.TELL_ACTIVE);
if(!runnableDemo.isRunning()) {
runnableDemo.run();
}
}
#Override
public void onDataError(String title) {
Log.i("TEST", "TestRunnable onResponse receive error Files: "+ title);
}
#Override
public void onDataSuccess(Response<ResponseBody> responseBody) {
Log.i("TEST", "TestRunnable onResponse receive success Files: "+ responseBody.code());
}
#Override
public void onStopped() {
Log.i("TEST", "TestRunnable onResponse receive onStopped Files: ");
}
}

MQTT send message from main thread

I have simple MQTT subscriber implemented in MqttHelper class that works fine and receives subscriptions. But how I should deal when I need to send message to server from main program. I have method publish that works fine from IMqttActionListener but how to send text from main program on button pressed event?
package com.kkk.mqtt.helpers;
import android.content.Context;
import android.util.Log;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import java.io.UnsupportedEncodingException;
public class MqttHelper {
public MqttAndroidClient mqttAndroidClient;
final String serverUri = "tcp://tailor.cloudmqtt.com:16424";
final String clientId = "ExampleAndroidClient";
public final String subscriptionTopic = "sensor";
final String username = "xxx";
final String password = "yyy";
public MqttHelper(Context context){
mqttAndroidClient = new MqttAndroidClient(context, serverUri, clientId);
mqttAndroidClient.setCallback(new MqttCallbackExtended() {
#Override
public void connectComplete(boolean b, String s) {
Log.w("mqtt", s);
}
#Override
public void connectionLost(Throwable throwable) {
}
#Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
Log.w("Mqtt", mqttMessage.toString());
}
#Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
}
});
connect();
}
public void setCallback(MqttCallbackExtended callback) {
mqttAndroidClient.setCallback(callback);
}
public void publish(String topic, String info)
{
byte[] encodedInfo = new byte[0];
try {
encodedInfo = info.getBytes("UTF-8");
MqttMessage message = new MqttMessage(encodedInfo);
mqttAndroidClient.publish(topic, message);
Log.e ("Mqtt", "publish done");
} catch (UnsupportedEncodingException | MqttException e) {
e.printStackTrace();
Log.e ("Mqtt", e.getMessage());
}catch (Exception e) {
Log.e ("Mqtt", "general exception "+e.getMessage());
}
}
private void connect(){
Log.w("Mqtt", "connect start " );
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setAutomaticReconnect(true);
mqttConnectOptions.setCleanSession(false);
mqttConnectOptions.setUserName(username);
mqttConnectOptions.setPassword(password.toCharArray());
try {
mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener()
{
#Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.w("Mqtt", "onSuccess " );
DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions();
disconnectedBufferOptions.setBufferEnabled(true);
disconnectedBufferOptions.setBufferSize(100);
disconnectedBufferOptions.setPersistBuffer(false);
disconnectedBufferOptions.setDeleteOldestMessages(false);
mqttAndroidClient.setBufferOpts(disconnectedBufferOptions);
subscribeToTopic();
publish(MqttHelper.this.subscriptionTopic,"information");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.w("Mqtt", "Failed to connect to: " + serverUri + exception.toString());
}
});
} catch (MqttException ex){
ex.printStackTrace();
}
}
private void subscribeToTopic() {
try {
mqttAndroidClient.subscribe(subscriptionTopic, 0, null, new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.w("Mqtt","Subscribed!");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.w("Mqtt", "Subscribed fail!");
}
});
} catch (MqttException ex) {
System.err.println("Exception whilst subscribing");
ex.printStackTrace();
}
}
}
Code that starts MQTT subscriber:
private void startMqtt() {
mqttHelper = new MqttHelper(getApplicationContext());
mqttHelper.setCallback(new MqttCallbackExtended()
{
#Override
public void connectComplete(boolean b, String s) {
Log.w("Mqtt", "Connect complete"+ s );
}
#Override
public void connectionLost(Throwable throwable) {
Log.w("Mqtt", "Connection lost" );
}
#Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
Log.w("Mqtt", mqttMessage.toString());
dataReceived.setText(mqttMessage.toString());
}
#Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
Log.w("Mqtt", "Delivery complete" );
}
});
Log.w("Mqtt", "will publish");
}
Paho does not run on the UI thread, but it may asynchronously call back to the UI thread.
Just let an Activity or Fragment implement the MqttCallbackExtended interface:
public class SomeActivity extends AppCompatActivity implements MqttCallbackExtended {
...
#Override
public void connectComplete(boolean reconnect, String serverURI) {
Log.d("Mqtt", "Connect complete > " + serverURI);
}
#Override
public void connectionLost(Throwable cause) {
Log.d("Mqtt", "Connection lost");
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
Log.d("Mqtt", "Received > " + topic + " > " + message.toString());
}
#Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.d("Mqtt", "Delivery complete");
}
}
And construct the MqttHelper with SomeActivity as it's MqttCallbackExtended listener:
public MqttHelper(Context context, MqttCallbackExtended listener) {
this.mqttAndroidClient = new MqttAndroidClient(context, serverUri, clientId);
this.mqttAndroidClient.setCallback(listener);
}
For example:
this.mqttHelper = new MqttHelper(this);
this.mqttHelper.setCallback(this);
this.mqttHelper.publish("Java", "SomeActivity will handle the callbacks.");
Handling these in Application is problematic, because Application has no UI and it's Context has no Theme. But for classes extending Activity, Fragment, DialogFragment, RecyclerView.Adapter, etc. it makes senses to implement the callback interface, when wanting to interact with their UI.
For reference, MqttCallbackExtended extends MqttCallback.
Another Solution:
Create a MQTTService class that extends android.app.Service.
Android Service class works in the main thread. So if you want to use another thread, you can use MqttAsyncClient simply.
You will receive messages from the broker in another thread automatically (not main thread) in messageArrived() using callback method.
Pass Data/command from the application UI (Activity-Fragment,...) to the MQTTService by EventBus library simply.
Again use the EventBus in the messageArrived() callback method to pass the received data from the broker to the desired section of your application.
Please note that in this step if your destination is an application UI, you have to use #Subscribe(threadMode = ThreadMode.MAIN) in the destination to get data in the main thread.
Sample Code:
public class MQTTService extends Service {
private MqttAsyncClient mqttClient;
private String serverURI;
#Override
public void onCreate() {
//do your initialization here
serverURI = "tcp://yourBrokerUrlOrIP:yourBrokerPort";
EventBus.getDefault().register(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
init();
connect();
}
private void init() {
mqttClient = new MqttAsyncClient(serverURI, yourClientId, new MemoryPersistence())
mqttClient.setCallback(new MqttCallback() {
#Override
public void connectionLost(Throwable cause) {
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
//now you will receive messages from the broker in another thread automatically (not UI Thread).
//You can do your logic here. for example pass the received data to the different sections of the application:
EventBus.getDefault().post(new YourPOJO(topic, message, ...));
}
#Override
public void deliveryComplete(IMqttDeliveryToken token) {
}
});
}
private MqttConnectOptions getOptions(){
MqttConnectOptions options = new MqttConnectOptions();
options.setKeepAliveInterval(...);
options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
options.setAutomaticReconnect(true);
options.setCleanSession(false);
options.setUserName(...);
options.setPassword(...);
//options.setWill(...);
//your other configurations
return options;
}
private void connect() {
try {
IMqttToken token = mqttClient.connect(getOptions(), null, new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
//do works after successful connection
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
#Override
public void onDestroy() {
EventBus.getDefault().unregister(this);
mqttClient.close();
mqttClient.disconnect();
}
//this method receives your command from the different application sections
//you can simply create different "MqttCommandPOJO" classes for different purposes
#Subscribe
public void receiveFromApp1(MqttCommandPOJO1 pojo1) {
//do your logic(1). For example:
//publish or subscribe something to the broker (QOS=1 is a good choice).
}
#Subscribe
public void receiveFromApp2(MqttCommandPOJO2 pojo2) {
//do your logic(2). For example:
//publish or subscribe something to the broker (QOS=1 is a good choice).
}
}
Now You can simply receive the data passed from the MQTTService in every section of your application.
For example:
public class MainActivity extends AppCompatActivity {
...
#Subscribe(threadMode = ThreadMode.MAIN)
public void receiveFromMQTTService(YourPojo pojo){
//Do your logic. For example update the UI.
}
}
Another links:
General instructions
Best wishes

Implementation of onDestroy to close a Billing Client

I am trying to make example of Play Billing application described here
In Last step they have described
To clean all the resources and unregister the observer, you just need to call BillingClient.endConnection. So define a method with this call inside BillingManager and then call it from GamePlayActivity.onDestroy:
according to above information I have made function called destroy like this in BillingManagerjava class.
public void destroy() {
mBillingClient.endConnection();
}
My Full BillingManager Class is like below
public class BillingManager implements PurchasesUpdatedListener {
private final BillingClient mBillingClient;
private final Activity mActivity;
private static final String TAG = "BillingManager";
public BillingManager(Activity activity) {
mActivity = activity;
mBillingClient = BillingClient.newBuilder(mActivity).setListener(this).build();
mBillingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingSetupFinished(#BillingClient.BillingResponse int billingResponse) {
if (billingResponse == BillingClient.BillingResponse.OK) {
Log.i(TAG, "onBillingSetupFinished() response: " + billingResponse);
} else {
Log.w(TAG, "onBillingSetupFinished() error code: " + billingResponse);
}
}
#Override
public void onBillingServiceDisconnected() {
Log.w(TAG, "onBillingServiceDisconnected()");
}
});
}
public void startPurchaseFlow(final String skuId, final String billingType) {
// Specify a runnable to start when connection to Billing client is established
Runnable executeOnConnectedService = new Runnable() {
#Override
public void run() {
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setType(billingType)
.setSku(skuId)
.build();
mBillingClient.launchBillingFlow(mActivity, billingFlowParams);
}
};
// If Billing client was disconnected, we retry 1 time
// and if success, execute the query
startServiceConnectionIfNeeded(executeOnConnectedService);
}
#Override
public void onPurchasesUpdated(#BillingClient.BillingResponse int responseCode,
List<Purchase> purchases) {
Log.d(TAG, "onPurchasesUpdated() response: " + responseCode);
}
private static final HashMap<String, List<String>> SKUS;
static
{
SKUS = new HashMap<>();
SKUS.put(BillingClient.SkuType.INAPP, Arrays.asList("gas", "premium"));
SKUS.put(BillingClient.SkuType.SUBS, Arrays.asList("gold_monthly", "gold_yearly"));
}
public List<String> getSkus(#BillingClient.SkuType String type) {
return SKUS.get(type);
}
public void querySkuDetailsAsync(#BillingClient.SkuType final String itemType,
final List<String> skuList, final SkuDetailsResponseListener listener) {
// Specify a runnable to start when connection to Billing client is established
Runnable executeOnConnectedService = new Runnable() {
#Override
public void run() {
SkuDetailsParams skuDetailsParams = SkuDetailsParams.newBuilder()
.setSkusList(skuList).setType(itemType).build();
mBillingClient.querySkuDetailsAsync(skuDetailsParams,
new SkuDetailsResponseListener() {
#Override
public void onSkuDetailsResponse(int responseCode,
List<SkuDetails> skuDetailsList) {
listener.onSkuDetailsResponse(responseCode, skuDetailsList);
}
});
}
};
// If Billing client was disconnected, we retry 1 time
// and if success, execute the query
startServiceConnectionIfNeeded(executeOnConnectedService);
}
private void startServiceConnectionIfNeeded(final Runnable executeOnSuccess) {
if (mBillingClient.isReady()) {
if (executeOnSuccess != null) {
executeOnSuccess.run();
}
} else {
mBillingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingSetupFinished(#BillingClient.BillingResponse int billingResponse) {
if (billingResponse == BillingClient.BillingResponse.OK) {
Log.i(TAG, "onBillingSetupFinished() response: " + billingResponse);
if (executeOnSuccess != null) {
executeOnSuccess.run();
}
} else {
Log.w(TAG, "onBillingSetupFinished() error code: " + billingResponse);
}
}
#Override
public void onBillingServiceDisconnected() {
Log.w(TAG, "onBillingServiceDisconnected()");
}
});
}
}
public void destroy() {
mBillingClient.endConnection();
}
}
And My GamePlayActivity is like below
public class GamePlayActivity extends FragmentActivity implements BillingProvider {
#Override
protected void onDestroy() {
super.onDestroy();
// I want call method here
}
}
Now I want call above function in my game play activity. I have no idea how to call it.
As it mentioned in documentation
call it from GamePlayActivity.onDestroy
but you defined your own method.
Override onDestroy method of GamePlayActivity and put mBillingClient.endConnection(); into it.
#Override
protected void onDestroy() {
mBillingClient.endConnection();
}
I assume your Activity already has an instance of the BillingManager
public class GamePlayActivity extends FragmentActivity implements BillingProvider {
BillingManager bm; // assign this in onCreate
#Override
protected void onDestroy() {
super.onDestroy();
bm.destroy();
}
}

Wait until socket as service gets available

I have read about Thread sleep, Handler, Runnable, AsyncTask and TimerTask, tried Thread sleep but could not figure out how can I accomplish the task.
I have implemented socket.io.client-java as service and using Volley as well as multiple activities & fragments. I need as follow:
Check if socket is connected before making Volley request.
If socket is connected then process Volley request otherwise re-check socket connectivity (a maximum of 5 times with 1 second interval).
In case of failure in 5 attempts, show a Toast message and continue the Volley request.
I 'm using a common class to perform Volley requests and others.
Socket Service
public class SocketClient extends Service {
private Socket mSocket = null;
private static SocketClient iSocket;
public SocketClient() {
super();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onCreate(){
super.onCreate();
iSocket = this;
startSocket();
}
public static synchronized SocketClient getInstance(){return iSocket;}
private void startSocket(){
try {
mSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
//...
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
//...
}
}).on(...{...});
mSocket.connect();
} catch (URISyntaxException e){
e.printStackTrace();
}
}
public boolean isConnected(){ return (mSocket != null && mSocket.connected()); }
#Override
public void onDestroy(){
super.onDestroy();
mSocket.disconnect().close();
mSocket = null;
}
}
Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
//...
Helpers.startServices(getApplicationContext(), 1);
}
#Override
protected void onResume() {
Helpers.getNotifed(); //A Volley Request
}
Helpers Class
public static void makeReq(Map<String, Object> params, String api, final Context context, final VolleyListener listener)
{
manager = new SessionManager(context);
final String url = baseURL + api;
int i = 0;
boolean ss = SocketClient.getInstance().isConnected();
Log.i(TAG, "Socket status" + ss);
while(i < 5 && !ss) {
try {
Log.i(TAG, "Socket status" + ss);
Log.i(TAG, "sleeping " + i);
Thread.sleep(1000);
ss = SocketClient.getInstance().isConnected();
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(!ss)
Toast.makeText(context, "Operation interrupt!", Toast.LENGTH_LONG).show();
//Volley JSON Object Request
}
public static void startServices(Context context, int st) {
switch (st) {
case 1: //Socket
if (!isServiceRunning(context, SocketClient.class))
context.startService(new Intent(context, SocketClient.class));
break;
}
}
Issues:
Getting NullPointerException at boolean ss = SocketClient.getInstance().isConnected(); as class might not initialized yet.
ANR (Application Not Responding) because the main Thread is halted in while loop.
P.S.: I'm just a beginner in Android/Java so reply with clear code would be appreciable.

QuickBlox chat messages listener

I use 2.1.1 Android SDK and want to notify user about new incoming messages received by application.
Here is the issue. I would like to notify user as he launches application, thus i would like to add listener at the stage of "user login" as it's shown in the snippet:
QBAuth.createSession(user, new QBEntityCallbackImpl<QBSession>() {
#Override
public void onSuccess(QBSession session, Bundle args) {
// login to Chat
chatService.login(user, new QBEntityCallbackImpl() {
#Override
public void onSuccess() {
HERE I WOULD LIKE A CODE TO START LISTEN FOR ALL INCOMING MESSAGES
As per http://sdk.quickblox.com/android/com/quickblox/chat/listeners/QBMessageListenerImpl.html
listener needs chat QBChat to initiate. But I would like to listen for all of the messages, not only within particular chat.
Long story short, how to implement a message listener to catch all messages addressed to logged in user?
#Naveen Kumar
In my start activity i launch listener to catch XMPP connection.
private void XMPPConnectionListener() {
XMPPConnection.addConnectionCreationListener(new ConnectionCreationListener() {
#Override
public void connectionCreated(XMPPConnection connection) {
GlobalVar.XMPPConn = connection;
ChatHelper.idleMessageListener(StartActivity.this);
}
});
}
Then I use GlobalVar.XMPPConn to catch packets and parse them:
public static void idleMessageListener(final Activity activity) {
PacketListener myListener = new PacketListener() {
public void processPacket(final Packet packet) {
final Integer userID = Integer.parseInt(returnIDFromPacket(packet.getFrom()));
final String body = returnBodyFromPacket(packet.toString());
if (!GlobalVar.currentOpponent.equals(userID) && !body.isEmpty()) {
activity.runOnUiThread(new Runnable() {
public void run() {
QBUsers.getUser(userID, new QBEntityCallbackImpl<QBUser>() {
#Override
public void onSuccess(final QBUser user, Bundle args) {
sendNotification(activity, user, body);
}
#Override
public void onError(List<String> errors) {
Log.d(TAG, errors.toString());
}
});
}
});
}
}
};
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
if (GlobalVar.XMPPConn != null) {
GlobalVar.XMPPConn.addPacketListener(myListener, filter);
}
}
So logic is to catch the connection fired by QuickBlox and then attach a packet listener to it.

Categories