En este artículo, estaríamos discutiendo una de las formas básicas de comunicación entre un programa en una PC y un dispositivo Android. Aquí usaremos el concepto de programación de Socket. Sabemos que la comunicación se lleva a cabo entre un remitente y un receptor, la programación de socket implica una configuración cliente-servidor, donde un cliente se conecta al servidor, envía el mensaje y el servidor en el otro extremo lo recibe. Ahora, esto puede ser unidireccional o bidireccional según su código.
¿Qué es la programación de sockets?
La programación de sockets es un método de comunicación entre dos dispositivos conectados a la misma red. Dos sockets, uno en el cliente y otro en el servidor, interactúan. Una dirección IP más un puerto conforman la dirección de un socket. Sobre el puerto especificado, la aplicación del servidor comienza a escuchar a los clientes. El cliente se conecta al servidor utilizando la dirección IP del servidor y el puerto que abre. Después de eso, la comunicación bidireccional es posible. Consulte esto para un concepto de profundidad:
En primer lugar, construyamos el programa que se ejecutará en el socket del servidor. Haremos PC como servidor y dispositivo Android como cliente.
Paso 1: Cree un nuevo proyecto en Eclipse.
Paso 2: Cree un servidor de clases.
Java
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class Server { // declaring required variables private static ServerSocket serverSocket; private static Socket clientSocket; private static InputStreamReader inputStreamReader; private static BufferedReader bufferedReader; private static String message=""; public static void main(String[] args) { try { // creating a new ServerSocket at port 4444 serverSocket = new ServerSocket(4444); } catch (IOException e) { System.out.println("Could not listen on port: 4444"); } System.out.println("Server started. Listening to the port 4444"); // we keep listening to the socket's // input stream until the message // "over" is encountered while (!message.equalsIgnoreCase("over")) { try { // the accept method waits for a new client connection // and and returns a individual socket for that connection clientSocket = serverSocket.accept(); // get the inputstream from socket, which will have // the message from the clients inputStreamReader = new InputStreamReader(clientSocket.getInputStream()); bufferedReader = new BufferedReader(inputStreamReader); // reading the message message = bufferedReader.readLine(); // printing the message System.out.println(message); // finally it is very important // that you close the sockets inputStreamReader.close(); clientSocket.close(); } catch (IOException ex) { System.out.println("Problem in message reading"); } } } }
Este programa cuando se ejecuta crea un ServerSocket en un puerto específico que es 4444. Ahora nuestro servidor comienza a escuchar las conexiones realizadas por los clientes que son dispositivos Android en este caso. Consulte este artículo para obtener más detalles: Ahora programemos la aplicación de Android para clientes.
Implementación paso a paso
Paso 1: Crear un nuevo proyecto
Para crear un nuevo proyecto en Android Studio, consulte Cómo crear/iniciar un nuevo proyecto en Android Studio . Tenga en cuenta que seleccione Java como lenguaje de programación.
Paso 2: trabajar con el archivo AndroidManifest.xml
XML
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.raghav.clientsocketapp"> <!--We require internet permission to perform networking tasks--> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.ClientSocketApp"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Paso 3: trabajar con el archivo activity_main.xml
Vaya a la aplicación > res > diseño > actividad_principal.xml y agregue el siguiente código a ese archivo. A continuación se muestra el código para el archivo activity_main.xml .
XML
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/editText1"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send" android:id="@+id/button1"/> </LinearLayout>
Paso 4: trabajar con el archivo MainActivity.java
Vaya al archivo MainActivity.java y consulte el siguiente código. A continuación se muestra el código del archivo MainActivity.java . Se agregan comentarios dentro del código para comprender el código con más detalle.
Java
import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import java.io.IOException; import java.io.PrintWriter; import java.net.Socket; public class MainActivity extends AppCompatActivity { // declaring required variables private Socket client; private PrintWriter printwriter; private EditText textField; private Button button; private String message; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // reference to the text field textField = (EditText) findViewById(R.id.editText1); // reference to the send button button = (Button) findViewById(R.id.button1); // Button press event listener button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // get the text message on the text field message = textField.getText().toString(); // start the Thread to connect to server new Thread(new ClientThread(message)).start(); } }); } // the ClientThread class performs // the networking operations class ClientThread implements Runnable { private final String message; ClientThread(String message) { this.message = message; } @Override public void run() { try { // the IP and port should be correct to have a connection established // Creates a stream socket and connects it to the specified port number on the named host. client = new Socket("192.168.43.114", 4444); // connect to server printwriter = new PrintWriter(client.getOutputStream(),true); printwriter.write(message); // write the message to output stream printwriter.flush(); printwriter.close(); // closing the connection client.close(); } catch (IOException e) { e.printStackTrace(); } // updating the UI runOnUiThread(new Runnable() { @Override public void run() { textField.setText(""); } }); } } }
Cuando se ejecuta en dispositivos con api11 o superior, obtendríamos una NetworkOnMainThreadException si hacemos la programación del socket en el subproceso principal. Para resolver esto, podemos usar la clase AsyncTask o crear un nuevo hilo. Dado que AsyncTask ya no es compatible con Android R, creamos un subproceso simple que realiza la parte de red.
Obtener la dirección IP correcta
Paso 1: habilite el punto de acceso de su dispositivo y conecte su PC a esta red (punto de acceso).
Paso 2: abra el símbolo del sistema y escriba el comando «ipconfig»
Paso 3: copie la dirección IPv4
Producción: