10

Wi-Fi を使用して、同じネットワーク内にあるすべてのモバイル間で UDP メッセージをブロードキャストするアプリを開発しています。

外部APを持つ多くの携帯電話からパケットを送受信することができました。それが私のルーターです。

しかし、AP がない場合でも、ユーザーが電話の Wifi ホットスポット機能を使用できるようにして、アプリケーションを引き続き使用できるようにしたいと考えています。つまり、携帯電話の 1 つが Wi-Fi ホットスポットになり、他のすべての携帯電話はそこに接続します。

私は、ユーザーが所有する Wi-Fi に接続することを要求しています。外部 AP または前述のホットスポットのいずれかに。次に、アプリケーションが起動すると、電話が Wi-Fi ネットワークに接続されているかどうかを確認し、WifiManager.isWifiEnabled() と NetworkInfo.isConnected() を呼び出します。

問題は、ホットスポットを使用している携帯電話でこれらの関数を呼び出すと、関数 isConnected() が false を返すことです。また、WifiManager.getDhcpInfo() を使用してブロードキャスト アドレスを取得できません。ホットスポットに接続されている他の電話は完全に機能します。ただし、WifiManager が無効になっているため、ホットスポット携帯電話はブロードキャストを送信できません。

そこで、私の質問は、「携帯電話が現在 Wi-Fi ホットスポットになっているかどうかを確認する方法はありますか?もしそうなら、そのブロードキャスト アドレスを取得する方法はありますか?」ということになります。

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;
}

もちろん1つの方法で行うこともできますが、私の実装では2つの方法に分けることが役に立ちました。

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 に答える