贝博恩创新科技网

Java如何打开USB互联网共享?

  1. 建立 USB 连接:在 Android 设备上,通过 USB 线连接另一台设备(如另一台 Android 手机、Windows PC 或树莓派),并开启“USB 网络共享”或“USB RNDIS”模式。
  2. 在 Java (Android) 中使用网络:一旦建立了网络连接,你的 Android 应用就可以像使用 Wi-Fi 或移动数据一样,通过标准的 Java 网络编程(如 HttpURLConnection, OkHttp, Socket 等)来访问互联网。

下面我将详细解释整个过程,包括前提条件、具体步骤、核心代码示例以及关键注意事项

Java如何打开USB互联网共享?-图1
(图片来源网络,侵删)

核心概念:Android USB 网络共享

当你在 Android 手机上开启“USB 网络共享”时,手机会通过 USB 线路模拟成一个网络适配器,对于另一端连接的设备(我们称之为客户端),它会获得一个由手机分配的 IP 地址(通常是 168.x.x 网段),你的 Android 应用运行在客户端设备上,它需要做的就是:

  1. 确保手机已开启 USB 网络共享。
  2. 通过标准 Java Socket 或 HTTP 客户端向服务器发起请求。
  3. 关键点:请求的目标服务器地址不是服务器的公网 IP,而是手机在 USB 网络中分配给客户端的网关 IP 地址

这个网关 IP 通常是 168.x.1168.x.2,你可以通过代码或系统设置来确认它。


详细步骤与代码实现

第 1 步:准备工作(在 Android 设备上)

  1. 物理连接:使用一根质量合格的 USB 线连接你的 Android 设备(客户端)和另一台设备(服务器,例如另一台手机或电脑)。
  2. 开启 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),因为很多设备都使用这个默认值。

Java如何打开USB互联网共享?-图2
(图片来源网络,侵删)

第 3 步:在 Java 代码中使用网络

一旦你有了网关 IP,就可以像使用普通网络一样进行通信了,这里我们使用 HttpURLConnectionOkHttp 两个例子。

假设你的服务器正在 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 (推荐,更现代和易用)

Java如何打开USB互联网共享?-图3
(图片来源网络,侵删)

在你的 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(() ->
分享:
扫描分享到社交APP
上一篇
下一篇