- 建立 USB 连接:在 Android 设备上,通过 USB 线连接另一台设备(如另一台 Android 手机、Windows PC 或树莓派),并开启“USB 网络共享”或“USB RNDIS”模式。
- 在 Java (Android) 中使用网络:一旦建立了网络连接,你的 Android 应用就可以像使用 Wi-Fi 或移动数据一样,通过标准的 Java 网络编程(如
HttpURLConnection,OkHttp,Socket等)来访问互联网。
下面我将详细解释整个过程,包括前提条件、具体步骤、核心代码示例以及关键注意事项。

核心概念:Android USB 网络共享
当你在 Android 手机上开启“USB 网络共享”时,手机会通过 USB 线路模拟成一个网络适配器,对于另一端连接的设备(我们称之为客户端),它会获得一个由手机分配的 IP 地址(通常是 168.x.x 网段),你的 Android 应用运行在客户端设备上,它需要做的就是:
- 确保手机已开启 USB 网络共享。
- 通过标准 Java Socket 或 HTTP 客户端向服务器发起请求。
- 关键点:请求的目标服务器地址不是服务器的公网 IP,而是手机在 USB 网络中分配给客户端的网关 IP 地址。
这个网关 IP 通常是 168.x.1 或 168.x.2,你可以通过代码或系统设置来确认它。
详细步骤与代码实现
第 1 步:准备工作(在 Android 设备上)
- 物理连接:使用一根质量合格的 USB 线连接你的 Android 设备(客户端)和另一台设备(服务器,例如另一台手机或电脑)。
- 开启 USB 网络共享:
- 在 Android 设备上,下拉通知栏。
- 长按“USB 已连接”或类似的通知。
- 在弹出的 USB 选项中,选择 “USB 网络共享” 或 “传输文件 (MTP)” 后,在系统设置中找到“移动热点和网络共享”并开启“USB 网络共享”。
- 成功后,连接的客户端设备应该会提示“已连接”,并且分配到了一个 IP 地址。
第 2 步:获取 USB 网关的 IP 地址
你的应用需要知道服务器的 IP 地址,这个地址就是 USB 网络的网关地址,你可以通过编程方式获取它。
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.List;
public class UsbNetworkUtils {
/**
* 尝试获取 USB 网络的网关 IP 地址。
* 通常会是 192.168.x.1 或 192.168.x.2
* @return 网关 IP 地址,如果找不到则返回 null
*/
public static String getUsbGatewayIpAddress() {
try {
// 获取所有网络接口
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces) {
// 忽略回环接口和没有活动的接口
if (intf.isLoopback() || !intf.isUp()) {
continue;
}
// 忽略 Wi-Fi 和移动数据接口,专注于 USB 接口
// USB 网络接口的名称通常是 "rndis0", "usb0" 等
String name = intf.getName();
if (!name.startsWith("rndis") && !name.startsWith("usb")) {
continue;
}
// 获取该接口上的所有 IP 地址
List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
for (InetAddress addr : addrs) {
String hostAddress = addr.getHostAddress();
// 确保是 IPv4 地址
if (!hostAddress.contains(":") && hostAddress.startsWith("192.168")) {
// 网关地址通常是该网段的第一个或第二个地址
// 192.168.x.1 或 192.168.x.2
// 这里我们简单返回找到的第一个符合条件的地址
// 在实际应用中,你可能需要更精确的逻辑来确定哪个是网关
return hostAddress;
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
return null;
}
}
注意:上面的代码是一个起点,在复杂的网络环境中,你可能需要更精确的逻辑来确定哪个 IP 地址是网关,一个更可靠的方法是检查路由表,但这在 Android 上比较麻烦,一个常见的做法是硬编码或通过配置文件指定 USB 网络的网段(如 168.42.1),因为很多设备都使用这个默认值。

第 3 步:在 Java 代码中使用网络
一旦你有了网关 IP,就可以像使用普通网络一样进行通信了,这里我们使用 HttpURLConnection 和 OkHttp 两个例子。
假设你的服务器正在 USB 网关 IP 的某个端口上监听 HTTP 请求(168.42.1:8080/api/data)。
示例 1:使用 HttpURLConnection (Java 标准库)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class UsbHttpExample {
public static String fetchDataFromUsbServer(String serverIp, String endpoint) {
String urlString = "http://" + serverIp + endpoint;
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
StringBuilder response = new StringBuilder();
try {
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setConnectTimeout(5000); // 5秒连接超时
urlConnection.setReadTimeout(10000); // 10秒读取超时
int responseCode = urlConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
} else {
// 处理错误响应
response.append("Error: HTTP ").append(responseCode);
}
} catch (IOException e) {
e.printStackTrace();
response.append("Error: ").append(e.getMessage());
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return response.toString();
}
}
示例 2:使用 OkHttp (推荐,更现代和易用)

在你的 app/build.gradle 文件中添加依赖:
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.12.0") // 使用最新版本
}
在代码中使用:
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class UsbOkHttpExample {
private final OkHttpClient client = new OkHttpClient();
public String fetchDataFromUsbServer(String serverIp, String endpoint) throws IOException {
String urlString = "http://" + serverIp + endpoint;
Request request = new Request.Builder()
.url(urlString)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
return response.body().string();
}
}
}
第 4 步:在 Activity 中调用
// 在你的 Activity 或其他组件中
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 1. 获取 USB 网关 IP
String serverIp = UsbNetworkUtils.getUsbGatewayIpAddress();
if (serverIp == null) {
Toast.makeText(this, "未检测到 USB 网络或无法获取网关IP", Toast.LENGTH_SHORT).show();
return;
}
// 2. 使用 IP 进行网络请求
// 假设服务器在 8080 端口提供 /api/data 接口
String endpoint = ":8080/api/data";
// 使用 OkHttp 示例
UsbOkHttpExample example = new UsbOkHttpExample();
new Thread(() -> {
try {
String result = example.fetchDataFromUsbServer(serverIp, endpoint);
// 切回主线程更新 UI
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "获取数据成功: " + result, Toast.LENGTH_LONG).show();
});
} catch (IOException e) {
e.printStackTrace();
runOnUiThread(() -> 