【问题标题】:Getting wifi broadcast address in Android wifi hotspot在Android wifi热点中获取wifi广播地址
【发布时间】:2020-12-31 13:05:07
【问题描述】:

我正在开发一个应用程序,它使用 wifi 在具有我的应用程序的同一网络中的所有手机之间广播 UDP 消息。

我设法从许多具有外部 AP(即我的路由器)的手机发送/接收数据包。

但鉴于没有 AP,我希望用户能够使用他们手机的 Wifi 热点功能,以便他们仍然可以使用我的应用程序。因此,其中一部手机将成为 wifi 热点,而其他所有手机都将连接到该热点。

我要求用户自己连接到 wifi。到外部 AP 或到所述热点。然后当我的应用程序启动时,它会检查手机是否连接到 wifi 网络,调用 WifiManager.isWifiEnabled() 和 NetworkInfo.isConnected()。

问题是,如果我在使用热点的手机中调用这些函数,函数 isConnected() 将返回 false。而且我无法使用 WifiManager.getDhcpInfo() 获取广播地址。 连接到热点的其他手机可以正常工作。但是热点手机无法发送任何广播,因为WifiManager被禁用了。

所以,我的问题是“有什么方法可以检查手机当前是否是 wifi 热点?如果是,有什么方法可以获取它的广播地址吗?”

【问题讨论】:

  • 你应该可以通过解析shell命令ip linkip route的结果得到你需要的东西

标签: android udp wifi broadcast


【解决方案1】:

首先你可以检查你的IP地址是什么:

public InetAddress getIpAddress() {
  InetAddress inetAddress = null;
  InetAddress myAddr = null;

  try {
    for (Enumeration<NetworkInterface> networkInterface = NetworkInterface
      .getNetworkInterfaces(); networkInterface.hasMoreElements();) {

      NetworkInterface singleInterface = networkInterface.nextElement();

      for (Enumeration<InetAddress> IpAddresses = singleInterface.getInetAddresses(); IpAddresses
        .hasMoreElements();) {
        inetAddress = IpAddresses.nextElement();

        if (!inetAddress.isLoopbackAddress() && (singleInterface.getDisplayName()
            .contains("wlan0") ||
            singleInterface.getDisplayName().contains("eth0") ||
            singleInterface.getDisplayName().contains("ap0"))) {

          myAddr = inetAddress;
        }
      }
    }

  } catch (SocketException ex) {
    Log.e(TAG, ex.toString());
  }
  return myAddr;
}

我使用这个 IP 以这种方式获取广播:

public InetAddress getBroadcast(InetAddress inetAddr) {

    NetworkInterface temp;
    InetAddress iAddr = null;
    try {
        temp = NetworkInterface.getByInetAddress(inetAddr);
        List<InterfaceAddress> addresses = temp.getInterfaceAddresses();

        for (InterfaceAddress inetAddress: addresses)

            iAddr = inetAddress.getBroadcast();
        Log.d(TAG, "iAddr=" + iAddr);
        return iAddr;

    } catch (SocketException e) {

        e.printStackTrace();
        Log.d(TAG, "getBroadcast" + e.getMessage());
    }
    return null;
}

当然可以用一种方法完成,但在我的实现中,将其分成两种方法很有用。

要确定 Wifi Tether 是否开启,您可以使用以下代码:

WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
Method[] wmMethods = wifi.getClass().getDeclaredMethods();
for (Method method: wmMethods) {
    if (method.getName().equals("isWifiApEnabled")) {

        try {
            if ((Boolean) method.invoke(wifi)) {
                isInetConnOn = true;
                iNetMode = 2;

            } else {
                Log.d(TAG, "WifiTether off");
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}

如果客户端设备需要知道服务器设备是否是移动热点,可以使用特定的 IP 地址。据我所知,所有网络共享设备都有相同的地址 192.168.43.1 它在 Android 2.3 和 4.+ 上是相同的,在许多手机和平板电脑上都检查过。当然这不是最好的解决方案,但它很快。在我的应用程序客户端设备检查(将数据包发送到此地址)和我的服务器设备以预定义的方式响应,例如“yesIamInTheterModeIamYourServer”。

【讨论】:

  • 这大概就是答案了,我一查就接受。这真的很有趣,但我不需要知道服务器是否是热点,因为我的应用程序中没有服务器(所有设备都发送和接收 UDP 广播)。非常感谢。
  • 该代码有一个小问题。这将检查所有接口,如果不是环回,则将地址设置为该环回。但我在我的设备上尝试过,它有 3 个接口,正确丢弃的环回 (127.0.0.1)、热点 (192.168.1.1) 和“ISP”(10.52.121.XXX)。然后它没有获得热点 wifi,但最后一个接口存在(在我的情况下,它是 ISP 接口)。无论如何,检查 IP 是否是私有 IP 就足够了,但是还有其他方法可以解决这个问题吗?
  • 我已经更新了我的答案,您可以检查现在还有一个条件,即检查交互名称。不同手机名称不同,一般是eth0或wlan0,但要检查wifi接口是否有其他名称
  • 是的,还有另一个名字。就我而言,它是 ap0。
  • 仅供参考,三星设备使用不同的地址,我相信它是 192.168.68.1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
  • 2012-03-23
  • 2014-06-17
  • 2013-05-19
  • 2014-05-25
相关资源
最近更新 更多