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

Is there a way to find out the gateway of a mobile network connection?

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

在API 级别 21 下存在 LinkProperties,但我的库不会被具有此 min 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的回应

来自设备的屏幕截图