By that I meant that the socket.io methods were moved from the application extended class into an android service class but I still kept getting multiple "hits" to the socket.io "on" methods regardless on the service thread being executed only once.
On Wed, Jan 20, 2016 at 5:31 PM, Justin Anderson <[email protected]> wrote: > What do you mean that moving calls to a device didn't work? That is most > likely what you want. I would implement it as a started and bound service. > > On Wed, Jan 20, 2016, 3:21 PM Gabriel Avila <[email protected]> wrote: > >> I'm trying to implement a globalized Socket.io connection method for an >> entire application (multiple activities). >> >> The requirements: >> 1. The socket.io must be enabled as long as the user is logged into the >> application >> 2. The socket has to keep connected even when switching activities. >> 3. The socket.io connection must be kept alive even when application is >> in background >> >> The Current Layout: >> 1. Socket.io methods are implemented in a class that extends the >> application class >> >> The Main Issues: >> 1. When emitting from the server to the Android the socket.io "on" >> methods are executed multiple times. The server code has been validated and >> determined it is only sending one emit to the client. >> 2. If I emit the methods from the server multiple times the "on" method >> execution increases exponentially. >> >> The Previous Solution: >> 1. Moved all the Socket.io methods into an Android Service but it did not >> work. >> >> What can I do to solve this? Am I missing something else? From what I >> read on other posts The singleton class will be elegible for termination by >> the OS once the application moves into the background, how can I avoid this? >> >> Here is my Application Extended Class >> >> public class AppSettings extends Application { >> >> private static String TAG = "AppSettings"; >> private static String username; >> private boolean isdriver; >> private int time, Buffer, intents; >> public CountDownTimer Clock; >> public Context mainContext; >> GOGODBHelper mGOGODBHelper; >> SQLiteDatabase db; >> private URI uri; >> public static Socket mSocket; >> public static long transaction_id = 0; >> >> { >> try { >> uri = new URI("http://gogosocket.cloudapp.net:3000"); >> AppSettings.this.mSocket = IO.socket(uri); >> >> } catch (URISyntaxException e) { >> Log.d(TAG, e.getMessage()); >> } >> } >> @Override >> public void onCreate() { >> super.onCreate(); >> final Fabric fabric = new Fabric.Builder(this) >> .kits(new Crashlytics()) >> .debuggable(true) >> .build(); >> Fabric.with(this, new Crashlytics()); >> >> mGOGODBHelper = new GOGODBHelper(this); >> >> registerReceiver(ConnectionReceiver, new >> IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); >> >> } >> >> public void setMainContext(Context context){ >> this.mainContext = context; >> } >> >> public Context getMainContext(){ >> return this.mainContext; >> } >> >> //set and get username >> public void setUsername(String username) { >> this.username = username; >> } >> >> public String getUsername() { >> return this.username; >> } >> >> //set and get isDriver >> public void setIsdriver(boolean isdriver) { >> this.isdriver = isdriver; >> } >> >> public boolean getIsdriver() { >> return this.isdriver; >> } >> >> private long saveTransaction(String to, String from,String >> event,String data,String timeStamp) { >> >> long newRowID = 0; >> >> db = mGOGODBHelper.getWritableDatabase(); >> >> ContentValues values = new ContentValues(); >> values.put(Transactions.Transaction.COLUMN_NAME_TO,to); >> values.put(Transactions.Transaction.COLUMN_NAME_FROM, from); >> values.put(Transactions.Transaction.COLUMN_NAME_METHOD,event); >> values.put(Transactions.Transaction.COLUMN_NAME_DATA,data); >> values.put(Transactions.Transaction.COLUMN_NAME_TIMESTAMP, >> timeStamp); >> >> newRowID = >> db.insert(Transactions.Transaction.TABLE_NAME,null,values); >> >> return newRowID; >> } >> >> private boolean deleteTransaction(long transaction_id){ >> db = mGOGODBHelper.getReadableDatabase(); >> >> return db.delete(Transactions.Transaction.TABLE_NAME, >> Transactions.Transaction._ID + " = " +transaction_id , null) >0; >> } >> >> public void onSocket() { >> AppSettings.this.mSocket.on(Socket.EVENT_CONNECT_ERROR, >> onConnectError) >> .on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError) >> .on(Socket.EVENT_RECONNECT_ERROR, onConnectError) >> .on(Socket.EVENT_RECONNECT_FAILED, onConnectError) >> .on(Socket.EVENT_DISCONNECT, onConnectError) >> .on(Socket.EVENT_ERROR, onConnectError) >> .on(Socket.EVENT_RECONNECT_ATTEMPT, onReconnect) >> .on(Socket.EVENT_RECONNECT, onReconnect) >> .on(Socket.EVENT_CONNECT, onConnect) >> .on("ping", ping) >> .on("method", method); >> // AppSettings.this.mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, >> onConnectError); >> // AppSettings.this.mSocket.on(Socket.EVENT_RECONNECT_ERROR, >> onConnectError); >> // AppSettings.this.mSocket.on(Socket.EVENT_RECONNECT_FAILED, >> onConnectError); >> // AppSettings.this.mSocket.on(Socket.EVENT_DISCONNECT, >> onConnectError); >> // AppSettings.this.mSocket.on(Socket.EVENT_ERROR, onConnectError); >> // AppSettings.this.mSocket.on(Socket.EVENT_RECONNECT_ATTEMPT, >> onReconnect); >> // AppSettings.this.mSocket.on(Socket.EVENT_RECONNECT, >> onReconnect); >> // AppSettings.this.mSocket.on(Socket.EVENT_CONNECT, onConnect); >> >> >> // this.mSocket.on("ping", ping); >> // this.mSocket.on("method", method); >> } >> >> public void offSocket() { >> AppSettings.this.mSocket.off(Socket.EVENT_CONNECT_ERROR, >> onConnectError) >> .off(Socket.EVENT_CONNECT_TIMEOUT, onConnectError) >> .off(Socket.EVENT_RECONNECT_ERROR, onConnectError) >> .off(Socket.EVENT_RECONNECT_FAILED, onConnectError) >> .off(Socket.EVENT_ERROR, onConnectError) >> .off(Socket.EVENT_DISCONNECT, onConnectError) >> .off(Socket.EVENT_RECONNECT, onReconnect) >> .off(Socket.EVENT_RECONNECT_ATTEMPT, onReconnect) >> .off("ping", ping) >> .off("method", method); >> // AppSettings.this.mSocket.off(Socket.EVENT_CONNECT_TIMEOUT, >> onConnectError); >> // AppSettings.this.mSocket.off(Socket.EVENT_RECONNECT_ERROR, >> onConnectError); >> // AppSettings.this.mSocket.off(Socket.EVENT_RECONNECT_FAILED, >> onConnectError); >> // AppSettings.this.mSocket.off(Socket.EVENT_ERROR, >> onConnectError); >> // AppSettings.this.mSocket.off(Socket.EVENT_DISCONNECT, >> onConnectError); >> // AppSettings.this.mSocket.off(Socket.EVENT_RECONNECT, >> onReconnect); >> // AppSettings.this.mSocket.off(Socket.EVENT_RECONNECT_ATTEMPT, >> onReconnect); >> // AppSettings.this.mSocket.off("ping", ping); >> // AppSettings.this.mSocket.off("method", method); >> } >> >> BroadcastReceiver ConnectionReceiver = new BroadcastReceiver() { >> @Override >> public void onReceive(Context context, Intent intent) { >> >> //startActivity(new Intent(AppSettings.this, >> LoginActivity.class)); >> >> } >> }; >> >> public long setTimeout(int B, int T, int I, int D) { >> long result = 0; >> >> if (D > 0) { >> result = ((B + T * I) * D); >> } else { >> result = B + T * I; >> } >> >> return result; >> } >> >> public void setBuffer(int buffer) { >> this.Buffer = buffer; >> } >> >> public int getBuffer() { >> return this.Buffer; >> } >> >> public void setTime(int time) { >> this.time = time; >> } >> >> public int getTime() { >> return this.time; >> } >> >> public void startClockWaitTime(Context context,final int B, final int >> T, final int I, final int D) { >> >> >> ((Activity)context).runOnUiThread(new Runnable() { >> @Override >> public void run() { >> if (AppSettings.this.Clock == null) { >> >> AppSettings.this.Clock = >> AppSettings.this.setClockWaitTime(B, T, I, D); >> AppSettings.this.Clock.start(); >> Log.d(TAG, "CountDownTimer was starting"); >> } >> } >> }); >> } >> >> public void stopClockWaitTime(Context context) { >> >> ((Activity)context).runOnUiThread(new Runnable() { >> @Override >> public void run() { >> if (AppSettings.this.Clock != null) { >> AppSettings.this.Clock.cancel(); >> AppSettings.this.Clock = null; >> >> Log.d(TAG, "CountDownTimer was stoped"); >> } >> >> } >> }); >> } >> >> public CountDownTimer setClockWaitTime(int B, int T, int I, int D) { >> >> >> CountDownTimer result; >> long waitTime = setTimeout(B, T, I, D) * 1000; >> Log.d(TAG, "Waitime: " + waitTime); >> >> result = new CountDownTimer(waitTime, 1000) { >> @Override >> public void onTick(long millisUntilFinished) { >> >> Log.d(TAG, "CountDownTimer tick"); >> } >> >> @Override >> public void onFinish() { >> >> Log.d(TAG, "CountDownTimer finish"); >> >> AppSettings.this.reconnect(); >> >> if (AppSettings.this.Clock != null) { >> AppSettings.this.Clock.cancel(); >> AppSettings.this.Clock = null; >> } >> } >> }.start(); >> >> Log.d(TAG, "CountDownTimer was set"); >> return result; >> } >> >> public boolean isConnected() { >> >> boolean result = false; >> >> if (AppSettings.this.mSocket != null && >> AppSettings.this.mSocket.connected() ) { >> result = true; >> } >> >> return result; >> } >> >> public void connect() { >> if (AppSettings.this.mSocket != null) { >> if(AppSettings.this.mSocket.connect() == null){ >> reconnect(); >> } >> >> } >> } >> >> private void ResetTravelElements() { >> Session.setSelectedLocation(null); >> Session.setSelectedDestination(null); >> Session.setEstimateDistance(0); >> Session.setEstimatePayment(null); >> Session.setPaxCount(null); >> Session.setBagCount(null); >> Session.setTypeVehicle(null); >> Session.setTotalTravelled(0); >> Session.resetWaitInstance(); >> Session.setStartWaitTime(0); >> } >> >> public void reconnect(){ >> >> Intent intent_expirate = new Intent("expirate"); >> intent_expirate.putExtra("message", "Reconnection - Comunication >> Error"); >> >> LocalBroadcastManager.getInstance(AppSettings.this).sendBroadcast(intent_expirate); >> >> >> } >> >> >> public void Emit(JSONObject jsonObject, int B, int T, int I, int D) { >> >> try { >> >> SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy >> hh:mm:ss"); >> Calendar c = Calendar.getInstance(); >> this.transaction_id = >> saveTransaction(null,getUsername(),jsonObject.getString("event"),jsonObject.toString(),df.format(c.getTime())); >> >> jsonObject.put("TID",transaction_id); >> >> if(AppSettings.this.mSocket.emit("method", jsonObject) == >> null){ >> reconnect(); >> return; >> } >> >> Log.d(TAG, this.getUsername() + " emit the event: " + >> jsonObject.getString("event")); >> >> LogFile(getApplicationContext(),String.valueOf(transaction_id), >> AppSettings.this.mSocket.id(),AppSettings.this.mSocket.id >> (),jsonObject.getString("event"),this.getUsername() >> ,Session.getDriver(),Session.getEmei()); >> >> if (AppSettings.this.Clock == null) { >> >> if(getMainContext() != null){ >> >> AppSettings.this.startClockWaitTime(this.getMainContext(), B, T, I, D); >> } >> >> } >> >> >> >> } catch (JSONException e) { >> e.printStackTrace(); >> } >> } >> >> >> >> private Emitter.Listener onConnectError = new Emitter.Listener() { >> @Override >> public void call(final Object... args) { >> //final JSONObject data = (JSONObject) args[0]; >> >> Log.i("Data", String.valueOf(args[0])); >> >> AppSettings.this.connect(); >> >> if (!AppSettings.this.isConnected()){ >> >> Log.d(TAG, "onConnectError Socket disconnected"); >> if(AppSettings.this.Clock == null){ >> if(getMainContext() != null){ >> >> AppSettings.this.startClockWaitTime(AppSettings.this.getMainContext(),15, >> 15, 1, 0); >> } >> } >> >> AppSettings.this.reconnect(); >> } >> } >> }; >> >> private Emitter.Listener onReconnect = new Emitter.Listener() { >> @Override >> public void call(final Object... args) { >> >> Log.i("onReconect Data", String.valueOf(args[0])); >> JSONObject object = new JSONObject(); >> >> if(AppSettings.this.isConnected()){ >> >> try{ >> object.put("event","join"); >> object.put("uid", username); >> AppSettings.this.Emit(object, 15, 15, 1, 0); >> } >> catch (JSONException e){ >> Log.d(TAG,e.getMessage()); >> } >> }else{ >> AppSettings.this.reconnect(); >> } >> } >> }; >> >> private Emitter.Listener onConnect = new Emitter.Listener() { >> @Override >> public void call(Object... args) { >> try { >> >> if(isConnected()){ >> >> JSONObject object = new JSONObject(); >> object.put("event", "join"); >> object.put("uid", username); >> AppSettings.this.Emit(object, 15, 15, 1, 0); >> } >> else { >> AppSettings.this.reconnect(); >> } >> >> >> } catch (JSONException e) { >> Log.d(TAG, e.getMessage()); >> } >> >> } >> }; >> >> private Emitter.Listener ping = new Emitter.Listener() { >> @Override >> public void call(final Object... args) { >> >> Log.i("Data", String.valueOf(args[0])); >> try { >> JSONObject object = new JSONObject(); >> object.put("beat", 1); >> AppSettings.this.mSocket.emit("pong", object); >> } catch (JSONException e) { >> Log.d(TAG, e.getMessage()); >> } >> } >> }; >> >> public static void LogFile(Context context,String transaction,String >> socketID,String receivedID,String methodSocket,String userID,boolean >> Taxiser,String imei){ >> try { >> // Creates a trace file in the primary external storage space >> of the >> // current application. >> // If the file does not exists, it is created. >> >> Calendar c = Calendar.getInstance(); >> SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy >> hh:mm:ss"); >> File traceFile = new File(context.getExternalFilesDir(null), >> "GPS_Data.csv"); >> if (!traceFile.exists()) >> traceFile.createNewFile(); >> // Adds a line to the trace file >> BufferedWriter writer = new BufferedWriter(new >> FileWriter(traceFile, true /*append*/)); >> writer.write(df.format(c.getTime()) +", "+ transaction + ", >> "+socketID+", " >> +receivedID+", "+ methodSocket+", "+userID+", >> "+Taxiser+'\n'); >> writer.close(); >> // Refresh the data so it can seen when the device is plugged >> in a >> // computer. You may have to unplug and replug the device to >> see the >> // latest changes. This is not necessary if the user should >> not modify >> // the files. >> MediaScannerConnection.scanFile(context, >> new String[]{traceFile.toString()}, >> null, >> null); >> >> } catch (IOException e) { >> //Log.d("com.cindypotvin.FileTest", "Unable to write to the >> TraceFile.txt file."); >> } >> } >> >> private Emitter.Listener method = new Emitter.Listener() { >> @Override >> public void call(Object... args) { >> >> try { >> >> long tid = 0; >> >> JSONObject received_object = (JSONObject) args[0]; >> String method = received_object.getString("event"); >> >> Log.d(TAG,"method: "+method+" is called..."); >> >> if(!method.equals("received")) { >> JSONObject sender_object = new JSONObject(); >> sender_object.put("TID", >> received_object.getString("TID")); >> sender_object.put("event","received"); >> AppSettings.this.mSocket.emit("method", >> sender_object); >> }else{ >> tid = received_object.getLong("TID"); >> } >> >> switch (method){ >> case "DriverConfirmed": >> >> //Log.d(TAG,"Socket on DriverConfirm"); >> >> String driver = received_object.getString("UID"); >> String name = received_object.getString("Name"); >> String driverPhone = >> received_object.getString("Phone"); >> double lat = received_object.getDouble("lat"); >> double lng = received_object.getDouble("lon"); >> float rating = >> Float.parseFloat(received_object.getString("Rating")); >> String tripnum = >> received_object.getString("TripNum"); >> boolean answer = >> received_object.getBoolean("answer"); >> String driverphoto = >> received_object.getString("driverPhoto"); >> String vehiclephoto = >> received_object.getString("vehiclePhoto"); >> >> Intent intent_DriverConfirmed = new >> Intent("DriverConfirmed"); >> intent_DriverConfirmed.putExtra("driver",driver); >> intent_DriverConfirmed.putExtra("name",name); >> >> intent_DriverConfirmed.putExtra("driverPhone",driverPhone); >> intent_DriverConfirmed.putExtra("lat",lat); >> intent_DriverConfirmed.putExtra("lon",lng); >> intent_DriverConfirmed.putExtra("rating",rating); >> >> intent_DriverConfirmed.putExtra("tripnum",tripnum); >> intent_DriverConfirmed.putExtra("answer",answer); >> >> intent_DriverConfirmed.putExtra("driverphoto",driverphoto); >> intent_DriverConfirmed.putExtra("vehiclephoto", >> vehiclephoto); >> >> >> LocalBroadcastManager.getInstance(AppSettings.this).sendBroadcast(intent_DriverConfirmed); >> >> break; >> case "DriverSelected": >> >> //Log.d(TAG,"Socket on DriverSelected"); >> >> String pass = received_object.getString("pass"); >> int requestID = >> received_object.getInt("requestid"); >> double passlat = received_object.getDouble("lat"); >> double passlng = received_object.getDouble("lon"); >> >> Intent intent_DriverSelected = new >> Intent("DriverSelected"); >> intent_DriverSelected.putExtra("pass",pass); >> >> intent_DriverSelected.putExtra("requestID",requestID); >> intent_DriverSelected.putExtra("passlat",passlat); >> intent_DriverSelected.putExtra("passlng", >> passlng); >> >> if (Session.getCurrentLocationInfo() != null) { >> >> >> NotificationManagement.statiticsNotification(AppSettings.this, 1); >> Location mCurrentLocation = >> Session.getCurrentLocationInfo(); >> intent_DriverSelected.putExtra("driverlat", >> mCurrentLocation.getLatitude()); >> intent_DriverSelected.putExtra("driverlng", >> mCurrentLocation.getLongitude()); >> >> >> LocalBroadcastManager.getInstance(AppSettings.this).sendBroadcast(intent_DriverSelected); >> }else{ >> Log.d(TAG, "Current Location isn't >> available."); >> Intent intent = new Intent("LOCATION_STATUS"); >> intent.putExtra("message", "Localizacion no >> disponible"); >> >> LocalBroadcastManager.getInstance(AppSettings.this).sendBroadcast(intent); >> } >> >> break; >> case "TaxiArrived": >> >> //Log.d(TAG,"Socket on TaxiArrived"); >> >> //Verificar si logica sigue igual. >> Intent intent_TaxiArrived = new >> Intent("TaxiArrived"); >> >> LocalBroadcastManager.getInstance(AppSettings.this).sendBroadcast(intent_TaxiArrived); >> >> break; >> case "tripcancelled": >> >> // Log.d(TAG,"Socket on tripcancelled"); >> >> //Implementar logica de navegacion en activity >> waitTaxi,GetPassenger,PassengerTrip, >> ResetTravelElements(); >> >> Intent intent_tripcancelled = new >> Intent("tripcancelled"); >> >> LocalBroadcastManager.getInstance(AppSettings.this).sendBroadcast(intent_tripcancelled); >> >> break; >> case "currentfare": >> >> //Log.d(TAG,"Socket on currentfare"); >> >> String fare = received_object.getString("fare"); >> >> Intent intent_currentfare = new >> Intent("currentfare"); >> intent_currentfare.putExtra("fare", fare); >> >> LocalBroadcastManager.getInstance(AppSettings.this).sendBroadcast(intent_currentfare); >> >> break; >> case "endtrip": >> >> // Log.d(TAG,"Socket on endtrip"); >> >> String tripID = >> received_object.getString("tripid"); >> String final_fare = >> received_object.getString("fare"); >> String estimate = >> received_object.getString("estimate"); >> >> Intent intent_endtrip = new Intent("endtrip"); >> intent_endtrip.putExtra("tripid",tripID); >> intent_endtrip.putExtra("fare",final_fare); >> intent_endtrip.putExtra("estimate", estimate); >> >> >> LocalBroadcastManager.getInstance(AppSettings.this).sendBroadcast(intent_endtrip); >> break; >> case "location": >> >> //Log.d(TAG, "Socket on location"); >> >> float bearing = >> Double.valueOf(received_object.getString("bearing")).floatValue(); >> boolean billable = >> received_object.getBoolean("billable"); >> double distance = >> received_object.getDouble("dist"); >> double ltd = received_object.getDouble("lat"); >> double lon = received_object.getDouble("lon"); >> double speed = received_object.getDouble("spd"); >> String tripNum = >> received_object.getString("tripnum"); >> >> Intent intent_location = new Intent("location"); >> intent_location.putExtra("bearing",bearing); >> intent_location.putExtra("billable",billable); >> intent_location.putExtra("dist",distance); >> intent_location.putExtra("lat",ltd); >> intent_location.putExtra("lon",lon); >> intent_location.putExtra("spd",speed); >> intent_location.putExtra("lon",lon); >> intent_location.putExtra("tripnum", tripNum); >> >> >> LocalBroadcastManager.getInstance(AppSettings.this).sendBroadcast(intent_location); >> >> break; >> >> case "received": >> >> // Log.d(TAG, "Socket on received"); >> >> if(tid > 0){ >> if(deleteTransaction(tid)){ >> if(AppSettings.this.Clock != null){ >> if(getMainContext() != null){ >> >> AppSettings.this.stopClockWaitTime(AppSettings.this.getMainContext()); >> } >> } >> } >> }else{ >> if(AppSettings.this.Clock != null){ >> if(getMainContext() != null){ >> >> AppSettings.this.stopClockWaitTime(AppSettings.this.getMainContext()); >> } >> } >> } >> Intent intent_received = new Intent("received"); >> >> LocalBroadcastManager.getInstance(AppSettings.this).sendBroadcast(intent_received); >> >> return; >> >> >> case "PassengerReceipt": >> >> //Log.d(TAG,"Socket on PassengerReceipt"); >> >> String TID = received_object.getString("TripNum"); >> String passenger = >> received_object.getString("PID"); >> >> Intent intent_PassengerReceipt = new >> Intent("PassengerReceipt"); >> intent_PassengerReceipt.putExtra("tripnum", TID); >> intent_PassengerReceipt.putExtra("pass", >> passenger); >> >> LocalBroadcastManager.getInstance(AppSettings.this).sendBroadcast(intent_PassengerReceipt); >> >> break; >> } >> >> LogFile(getApplicationContext(), >> received_object.getString("TID"), AppSettings.this.mSocket.id(), >> AppSettings.this.mSocket.id(), received_object.getString("event"), >> AppSettings.this.getUsername() >> , Session.getDriver(), Session.getEmei()); >> } >> catch (JSONException e){ >> Log.d(TAG,e.getMessage()); >> } >> } >> }; >> } >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Android Developers" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> To post to this group, send email to [email protected]. >> Visit this group at https://groups.google.com/group/android-developers. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/android-developers/730fc15c-e5b7-449e-b0ed-64eb7eea688b%40googlegroups.com >> . >> For more options, visit https://groups.google.com/d/optout. >> > -- > You received this message because you are subscribed to a topic in the > Google Groups "Android Developers" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/android-developers/vs1OHCXQIFg/unsubscribe > . > To unsubscribe from this group and all its topics, send an email to > [email protected]. > To post to this group, send email to [email protected]. > Visit this group at https://groups.google.com/group/android-developers. > To view this discussion on the web visit > https://groups.google.com/d/msgid/android-developers/CAOq06s-AxNkuz4UuCk42cJFnZeA6uP3d7B9d4z4YTsxFGrqRpw%40mail.gmail.com > <https://groups.google.com/d/msgid/android-developers/CAOq06s-AxNkuz4UuCk42cJFnZeA6uP3d7B9d4z4YTsxFGrqRpw%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > > For more options, visit https://groups.google.com/d/optout. > -- Ing. Gabriel J. Avila Software Developer Engineer (787) 408 - 7015 -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/android-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/android-developers/CAD01ODqUDW1Go2%3DEJ-ZQVEXmnNMLVDJZy4zU5nNbfwA_3c%2BJNg%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.

