如何使用Android与PC通信?
在本文中,我们将讨论 PC 上的程序与 Android 设备之间的一种基本通信方式。这里我们会用到Socket编程的概念。我们知道通信发生在发送方和接收方之间,套接字编程涉及客户端-服务器设置,客户端连接到服务器,发送消息,另一端的服务器接收它。现在,根据您的代码,这可以是单向的或双向的。
什么是套接字编程?
套接字编程是一种在连接到同一网络的两个设备之间进行通信的方法。两个套接字,一个在客户端,一个在服务器,交互。 IP 地址加上端口构成了套接字的地址。通过指定的端口,服务器应用程序开始侦听客户端。客户端使用服务器的 IP 地址和它打开的端口连接到服务器。之后,双向通信成为可能。有关深度概念,请参阅此: Introducing Threads in Socket Programming in Java
首先,让我们构建要在服务器套接字上执行的程序。我们将PC作为服务器,Android设备作为客户端。
步骤 1:在 Eclipse 中创建一个新项目。
第 2 步:创建一个类服务器。
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");
}
}
}
}
XML
XML
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("");
}
});
}
}
}
该程序在执行时会在特定端口 4444 上创建一个 ServerSocket。现在我们的服务器开始侦听在这种情况下是 android 设备的客户端建立的连接。更多细节请参考这篇文章: Java的套接字编程。现在让我们为客户端编写 android 应用程序。
分步实施
第 1 步:创建一个新项目
要在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目。请注意,选择Java作为编程语言。
第 2 步:使用 AndroidManifest.xml 文件
XML
步骤 3:使用 activity_main.xml 文件
导航到app > res > layout > activity_main.xml并将以下代码添加到该文件中。下面是activity_main.xml文件的代码。
XML
第 4 步:使用MainActivity。 Java文件
转到主活动。 Java文件,参考如下代码。下面是MainActivity的代码。 Java文件。代码中添加了注释以更详细地理解代码。
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("");
}
});
}
}
}
当在 api11 或更高版本的设备上运行时,如果我们在主线程上进行套接字编程,我们会得到一个 NetworkOnMainThreadException。为了解决这个问题,我们可以使用 AsyncTask 类或创建一个新线程。由于 Android R 不再支持 AsyncTask,我们创建了一个简单的线程来执行网络部分。
获取正确的 IP 地址
步骤 1:启用设备的热点并将您的 PC 连接到此(热点)网络。
步骤2:打开命令提示符并写入命令“ipconfig”
步骤 3:复制 IPv4 地址
输出: