cómo crear una conexión de socket en Android?

Tengo una aplicación donde necesito crear una conexión de socket. Mi requerimiento es que, una vez que mi conexión de socket esté establecida, tenga que estar viva hasta que yo personalmente la cierre. Cada 3 minutos tengo que enviar paquetes de datos al otro extremo. ¿Alguien puede proporcionarme alguna muestra de código que me ayude a hacer esto?

Las conexiones de socket en Android son las mismas que en Java: http://www.oracle.com/technetwork/java/socket-140484.html

Cosas que debes tener en cuenta:

  1. Si el teléfono se queda dormido, su aplicación ya no se ejecutará, por lo que el socket eventualmente finalizará. Puedes evitar esto con el locking por activación. Esto consumirá muchísimo la batería de los dispositivos: sé que no usaría esa aplicación.
  2. Si haces esto constantemente, incluso cuando tu aplicación no esté activa, entonces debes usar el Servicio.
  3. El sistema operativo puede acabar con las actividades y los servicios en cualquier momento, especialmente si son parte de una aplicación inactiva.

Eche un vistazo a AlarmManager , si necesita la ejecución progtwigda de su código.

¿Necesita ejecutar su código y recibir datos incluso si el usuario ya no usa la aplicación (es decir, la aplicación está inactiva)?

Aquí, en esta publicación encontrará el código detallado para establecer el socket entre dispositivos o entre dos aplicaciones en el mismo dispositivo móvil.

Tienes que crear dos aplicaciones para probar el código a continuación.

En el archivo de manifiesto de ambas aplicaciones, agregue el permiso debajo

  

1er código de la aplicación: zócalo del cliente

activity_main.xml

 < ?xml version="1.0" encoding="utf-8"?>          

MainActivity.java

 import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; /** * Created by Girish Bhalerao on 5/4/2017. */ public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView mTextViewReplyFromServer; private EditText mEditTextSendMessage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button buttonSend = (Button) findViewById(R.id.btn_send); mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message); mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server); buttonSend.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_send: sendMessage(mEditTextSendMessage.getText().toString()); break; } } private void sendMessage(final String msg) { final Handler handler = new Handler(); Thread thread = new Thread(new Runnable() { @Override public void run() { try { //Replace below IP with the IP of that device in which server socket open. //If you change port then change the port number in the server side code also. Socket s = new Socket("xxx.xxx.xxx.xxx", 9002); OutputStream out = s.getOutputStream(); PrintWriter output = new PrintWriter(out); output.println(msg); output.flush(); BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream())); final String st = input.readLine(); handler.post(new Runnable() { @Override public void run() { String s = mTextViewReplyFromServer.getText().toString(); if (st.trim().length() != 0) mTextViewReplyFromServer.setText(s + "\nFrom Server : " + st); } }); output.close(); out.close(); s.close(); } catch (IOException e) { e.printStackTrace(); } } }); thread.start(); } } 

Código de la segunda aplicación: zócalo del servidor

activity_main.xml

 < ?xml version="1.0" encoding="utf-8"?>        

MainActivity.java

 import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * Created by Girish Bhalerao on 5/4/2017. */ public class MainActivity extends AppCompatActivity implements View.OnClickListener { final Handler handler = new Handler(); private Button buttonStartReceiving; private Button buttonStopReceiving; private TextView textViewDataFromClient; private boolean end = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonStartReceiving = (Button) findViewById(R.id.btn_start_receiving); buttonStopReceiving = (Button) findViewById(R.id.btn_stop_receiving); textViewDataFromClient = (TextView) findViewById(R.id.tv_data_from_client); buttonStartReceiving.setOnClickListener(this); buttonStopReceiving.setOnClickListener(this); } private void startServerSocket() { Thread thread = new Thread(new Runnable() { private String stringData = null; @Override public void run() { try { ServerSocket ss = new ServerSocket(9002); while (!end) { //Server is waiting for client here, if needed Socket s = ss.accept(); BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream())); PrintWriter output = new PrintWriter(s.getOutputStream()); stringData = input.readLine(); output.println("FROM SERVER - " + stringData.toUpperCase()); output.flush(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } updateUI(stringData); if (stringData.equalsIgnoreCase("STOP")) { end = true; output.close(); s.close(); break; } output.close(); s.close(); } ss.close(); } catch (IOException e) { e.printStackTrace(); } } }); thread.start(); } private void updateUI(final String stringData) { handler.post(new Runnable() { @Override public void run() { String s = textViewDataFromClient.getText().toString(); if (stringData.trim().length() != 0) textViewDataFromClient.setText(s + "\n" + "From Client : " + stringData); } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_start_receiving: startServerSocket(); buttonStartReceiving.setEnabled(false); buttonStopReceiving.setEnabled(true); break; case R.id.btn_stop_receiving: //stopping server socket logic you can add yourself buttonStartReceiving.setEnabled(true); buttonStopReceiving.setEnabled(false); break; } } } 

Ejemplo de aplicación de servidor de socket simple

Ya publiqué un ejemplo de cliente en: https://stackoverflow.com/a/35971718/895245 , así que aquí va un ejemplo de servidor.

Esta aplicación de ejemplo ejecuta un servidor que devuelve una cifra ROT-1 de la entrada.

Entonces necesitaría agregar un botón de Exit + algunas demoras en el sueño, pero esto debería comenzar.

Para jugar con esto:

Los conectores de Android son los mismos que los de Java, excepto que tenemos que lidiar con algunos problemas de permisos.

src / com / cirosantilli / android_cheat / socket

Necesitamos un Service u otro método de fondo o bien: ¿Cómo arreglar android.os.NetworkOnMainThreadException?

 package com.cirosantilli.android_cheat.socket; import android.app.Activity; import android.app.IntentService; import android.content.Intent; import android.os.Bundle; import android.util.Log; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; public class Main extends Activity { static final String TAG = "AndroidCheatSocket"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(Main.TAG, "onCreate"); Main.this.startService(new Intent(Main.this, MyService.class)); } public static class MyService extends IntentService { public MyService() { super("MyService"); } @Override protected void onHandleIntent(Intent intent) { Log.d(Main.TAG, "onHandleIntent"); final int port = 12345; ServerSocket listener = null; try { listener = new ServerSocket(port); Log.d(Main.TAG, String.format("listening on port = %d", port)); while (true) { Log.d(Main.TAG, "waiting for client"); Socket socket = listener.accept(); Log.d(Main.TAG, String.format("client connected from: %s", socket.getRemoteSocketAddress().toString())); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintStream out = new PrintStream(socket.getOutputStream()); for (String inputLine; (inputLine = in.readLine()) != null;) { Log.d(Main.TAG, "received"); Log.d(Main.TAG, inputLine); StringBuilder outputStringBuilder = new StringBuilder(""); char inputLineChars[] = inputLine.toCharArray(); for (char c : inputLineChars) outputStringBuilder.append(Character.toChars(c + 1)); out.println(outputStringBuilder); } } } catch(IOException e) { Log.d(Main.TAG, e.toString()); } } } } 

AndroidManifest.xml

Debe agregar: o bien: Java socket IOException – permission denied

 < ?xml version="1.0" encoding="utf-8"?>              

En GitHub con un build.xml : https://github.com/cirosantilli/android-cheat/tree/92de020d0b708549a444ebd9f881de7b240b3fbc/socket