java - 有没有办法找出移动网络连接的网关?

标签 java android networking gateway

您好,我想阅读有关移动网络连接的详细信息,例如 IP 地址、DNS 服务器等以及网络通常用于向互联网发送数据的网关。由于这是 TCP/IP 连接,因此必须有一个连接。所以我试图寻找解决方案或示例来找出移动网络连接的网关(不是Wifi!!!)。

在 API 级别 21 下,存在 LinkProperties,但具有此最小 SDK 的平板电脑和智能手机不会使用我的库。

所以在 LOLLIPOP 下我确实有这个解决方案

if (Utils.hasLollipop()) {
                LinkProperties linkProperties = connectivityManager.getLinkProperties(mobileNetwork);

                if (linkProperties != null) {
                    List<InetAddress> dnsServers = linkProperties.getDnsServers();

                    for (InetAddress dns : dnsServers) {
                        if (!status.getmDNS().contains(dns.getHostAddress())) {
                            status.getmDNS().add(dns.getHostAddress());
                        }
                    }

                    List<RouteInfo> routeInfos = linkProperties.getRoutes();

                    if (routeInfos != null && routeInfos.size() > 0) {
                        for (RouteInfo i : routeInfos) {
                            if (i.getGateway() != null) {
                                status.setmGateway(i.getGateway().getHostAddress());
                                break;
                            }
                        }
                    }
                }
            } else {
              ... Solution for devices API Level < 21
            }

有人知道我能做什么吗?!

谢谢;D

编辑:

根据“Lance Preston”的答案的评论,我确实编写了示例代码。如果有任何其他方法,或者您有任何错误修复,请告诉我们。

private static final String ipv4Pattern = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}";
private static final String interfacePattern = "\\s*dev\\s*";
private static final String defaultGatewayPattern = "default\\s*via\\s*";
private static final String noCapturingPattern = "(?:%s)";

public static List<String> getGateways(String interfaceName) {
    try {
        List<String> gateways = new ArrayList<>();
        Pattern defaultpattern = Pattern.compile(String.format(noCapturingPattern, defaultGatewayPattern) + "(" + ipv4Pattern + ")" + String.format(noCapturingPattern, (interfacePattern + interfaceName)));
        Pattern ipAddressPattern = Pattern.compile(String.format(noCapturingPattern, ipv4Pattern + "\\s*via\\s*") + "(" + ipv4Pattern + ")" + String.format(noCapturingPattern, (interfacePattern + interfaceName)));
        Process result = Runtime.getRuntime().exec("ip route show");
        BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));
        String line = output.readLine();

        while (line != null) {
            if (!line.isEmpty()) {
                Matcher defaultMatcher = defaultpattern.matcher(line);
                if (defaultMatcher.find() && defaultMatcher.groupCount() == 1) {
                    String gatewayAddress = defaultMatcher.group(1);
                    if (gatewayAddress != null && !gatewayAddress.isEmpty() && !gateways.contains(gatewayAddress)) {
                        gateways.add(gatewayAddress);
                    }
                }

                Matcher ipAddressMatcher = ipAddressPattern.matcher(line);
                if (ipAddressMatcher.find() && ipAddressMatcher.groupCount() == 1) {
                    String gatewayAddress = ipAddressMatcher.group(1);
                    if (gatewayAddress != null && !gatewayAddress.isEmpty() && !gateways.contains(gatewayAddress)) {
                        gateways.add(gatewayAddress);
                    }
                }
            }
            line = output.readLine();
        }

        return gateways;

    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

最佳答案

此 Linux 命令可以借用一些网关信息 - netstat -r -nip route show
然后,您可以沿着 default via xxx.xxx.xxx.xxx

解析 ip route show 的输出

这会对你有所帮助。

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class MainActivity extends AppCompatActivity {

TextView tv;
EditText et;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tv = (TextView) findViewById(R.id.out);
    et = (EditText) findViewById(R.id.txt);

    String [] res = executeInShell("ip route show").split("\n");
    String gatewayInfo [] = res[0].split(" ");

    et.setText("ip route show");
    et.setSelection(et.getText().length());

    tv.setText(gatewayInfo[2].toString());

    Log.d("Response", executeInShell("ip route show"));


}

public static String executeInShell(String command) {

        StringBuffer output = new StringBuffer();

        Process p;
        try {
            p = Runtime.getRuntime().exec(command);
            p.waitFor();
            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

            String line = "";
            while ((line = reader.readLine())!= null) {
                output.append(line + "\n");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        String response = output.toString();
        return response;

   }

}


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="center"
tools:context=".MainActivity" >

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="20sp"
    android:gravity="center"
    android:textAlignment="center"
    android:text="Get My Gateway" />
<EditText
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/txt" />
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/out"
    android:gravity="center_horizontal" />

来自 LogCat 的响应

Response from LogCat

设备屏幕截图

Screenshot from device

关于java - 有没有办法找出移动网络连接的网关?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35722676/

相关文章:

java - 如何在 Android studio 中的 Runnable() 中断中设置断点?

java - 更新到4.2RC1,透明 Activity 不行?突然变黑

java - HttpsURLConnection 不适用于 Android API 19(但适用于 API 22 至 29)

java - Jackson 反序列化对象内部字段

c - MAC 地址的网络字节顺序

java - 无法将 boolean 值更改为 true

java - 如何设置 Postgres 数据源的事务隔离级别

java - 枚举内部类不被识别为枚举

android - 显示虚拟键盘时调整 QML 窗口大小

java - 将字符串值(日期)从 Activity 传递到另一个 fragment 的 TextView