studio servidor programacion móviles libros desarrollo curso con cliente aplicaciones android sockets client-server asyncsocket

servidor - manual de programacion android pdf



¿Cómo mantener el cliente de Android conectado al servidor incluso en los cambios de actividad y enviar datos al servidor? (2)

Inicialmente implementé una tarea asíncrona en mi actividad que envía datos al servidor. Pero cuando cambié de actividad se perdió la conexión. Para evitar esto, mi enfoque fue implementar un servicio que centralice la operación de la red y envíe datos al servidor y el código para este servicio se proporciona a continuación.

import java.io.BufferedWriter; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; import android.widget.Toast; public class SocketService extends Service { public static final String SERVERIP = ""; //your computer IP address should be written here public static final int SERVERPORT = 5000; PrintWriter out; Socket socket; InetAddress serverAddr; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub System.out.println("I am in Ibinder onBind method"); return myBinder; } private final IBinder myBinder = new LocalBinder(); TCPClient mTcpClient = new TCPClient(); public class LocalBinder extends Binder { public SocketService getService() { System.out.println("I am in Localbinder "); return SocketService.this; } } @Override public void onCreate() { super.onCreate(); System.out.println("I am in on create"); } public void IsBoundable(){ Toast.makeText(this,"I bind like butter", Toast.LENGTH_LONG).show(); } public void sendMessage(String message){ if (out != null && !out.checkError()) { System.out.println("in sendMessage"+message); out.println(message); out.flush(); } } @Override public int onStartCommand(Intent intent,int flags, int startId){ super.onStartCommand(intent, flags, startId); System.out.println("I am in on start"); // Toast.makeText(this,"Service created ...", Toast.LENGTH_LONG).show(); Runnable connect = new connectSocket(); new Thread(connect).start(); return START_STICKY; } class connectSocket implements Runnable { @Override public void run() { try { //here you must put your computer''s IP address. serverAddr = InetAddress.getByName(SERVERIP); Log.e("TCP Client", "C: Connecting..."); //create a socket to make the connection with the server 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."); } catch (Exception e) { Log.e("TCP", "S: Error", e); } } catch (Exception e) { Log.e("TCP", "C: Error", e); } } } @Override public void onDestroy() { super.onDestroy(); try { socket.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } socket = null; } }

Rotator.java es mi actividad que vinculo a este servicio. A continuación hay algunas piezas de código de mi actividad.

private ServiceConnection mConnection = new ServiceConnection() { //EDITED PART @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub mBoundService = ((SocketService.LocalBinder)service).getService(); } @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub mBoundService = null; } }; private void doBindService() { bindService(new Intent(Rotator.this, SocketService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; if(mBoundService!=null){ mBoundService.IsBoundable(); } } private void doUnbindService() { if (mIsBound) { // Detach our existing connection. unbindService(mConnection); mIsBound = false; } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); gestureDetector = new GestureDetector(this, new GestureListener()); setContentView(R.layout.activity_rotator); //Binding the activity to the service to perform client-server operations //start service on create startService(new Intent(Rotator.this,SocketService.class)); doBindService(); ........... ........... } @Override protected void onDestroy() { super.onDestroy(); doUnbindService(); }

Ahora, como este servicio se ejecuta en segundo plano, si quiero enviar algunos datos al servidor, uso lo siguiente

if(mBoundService!=null) { mBoundService.sendMessage("right"); }


Cuando un servicio está vinculado a una Activity , se cancela cuando se detiene la actividad, es como un servicio en segundo plano solo para la Activity . Por lo tanto, para mantenerlo en funcionamiento, implemente el método onStartCommand() en su clase de Service y devuelva this.START_STICKY . y gestione su servicio en este método.


El código es correcto. El único error fue que estaba intentando iniciar el servicio dos veces una vez en el método onServiceConnected () y el otro en el método onCreate ().

Cambié mi código para iniciar el servicio solo en el método onCreate () en la actividad del iniciador. El resto de las actividades se enlazan directamente al servicio utilizando el método doBindService ()