10

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

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

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

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

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

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

4

1 回答 1

15

首先,您可以检查您的 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”。

于 2012-12-29T12:32:55.967 回答