【问题标题】:How to specify wifi network with NetworkRequest.Builder().setNetworkSpecifier(string)如何使用 NetworkRequest.Builder().setNetworkSpecifier(string) 指定 wifi 网络
【发布时间】:2025-12-31 08:15:12
【问题描述】:

出于安全原因,我正在寻找一种让 Android 5.0 平板电脑连接到没有互联网连接的 Intranet 的方法。

问题是 Google 自 4.4/5.0 以来在 android 中构建的强制门户保护。 呼叫android connectivitycheck 以检查互联网连接,当此呼叫失败时,wifi 网络被标记为不工作并避免。很蹩脚。

其他人也遇到了同样的问题,有些人建议使用 android 5 中引入的新 API,请参阅: Android 5.0 Lollipop and 4.4 KitKat ignores my WiFi network, enableNetwork() is useless

这方面的文档非常模糊:

NetworkRequest.Builder.setNetworkSpecifier(String  networkSpecifier)

“此字符串的解释是特定于承载的,使用它的承载应记录其详细信息。例如,蓝牙可能使用某种设备 ID,而 WiFi 可能使用 ssid 和/或 bssid。蜂窝移动可能使用运营商spn"

我试过了,但它不起作用。主要问题是一旦我使用setNetworkSpecifier() 就找不到网络。我尝试使用 AP 的bssid (mac) 和ssid

看起来过滤器正在工作,但不清楚它应该如何工作。 如果我遗漏了setNetworkSpecifier() call 1 网络,则无法确定是哪个网络。至少它表明我的代码有效。

如果 ssid 和 bssid 不起作用,我应该在这里输入什么?

这是我的代码。

 private void connect(String ssid, Context context) {
    Log.i(TAG, "try connect to! " + ssid);
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).
                removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED).
                removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET

                setNetworkSpecifier(ssid). //<--- here is the problem
                build();
        ConnectivityManager.NetworkCallback callback 
             = new ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(Network network) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        Log.i(TAG, "onAvailable " + network.toString() + " " + network.getClass().getName());
                }
            }

            @Override
            public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
                try {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        Log.i(TAG, "onCapabilitiesChanged " + networkCapabilities.getLinkDownstreamBandwidthKbps());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
                try {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        Log.i(TAG, "onLinkPropertiesChanged " + linkProperties.getInterfaceName());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        Log.i(TAG, "requestNetwork ");
        // cm.requestNetwork(nr, callback);
        cm.registerNetworkCallback(nr, callback);
    }
}

【问题讨论】:

  • 您找到解决方案了吗?
  • 不,仍然没有找到方法,唉
  • 嘿,有一些好消息(在 Android Q 上)-developer.android.com/preview/features#peer2peer
  • 我也有同样的情况。所以我放 NetworkSpecifier 的时候不工作,不放也可以。

标签: android networking android-wifi captiveportal


【解决方案1】:

我在 Android Studio 的三星 S5 (SM-G900V)、API 23 (6.0.1) 上调试了以下代码。

void inspectNetworks() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        ConnectivityManager connectivity = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        Network[] ns = connectivity.getAllNetworks();
        for (Network n : ns) {
            NetworkCapabilities c = connectivity.getNetworkCapabilities(n);
            Log.i(TAG, "inspectNetworks: network="+n+" capabilities="+c); // <- breakpoint
        }
    }
}

我发现 Wi-Fi 网络根本没有networkSpecifier

也许networkSpecifiers for WIFI-transport 网络将在未来实施...作为记录,我发现 networkSpecifier 在此特定上设置为 1现有CELLULAR-transport 网络的电话。

就目前而言,在请求 Wi-Fi 网络时,调用 addCapability 似乎尽可能具体。

【讨论】:

    【解决方案2】:

    首先作弊始终是一种选择,只需要人们更改手机中的设置才能使用网络。骗子是这样的。 Wifi->高级->未选中。

    但是,我确定这不是您要寻找的答案。所以我为你做了一些研究,找到了需要的东西。您需要调用命令ignoreNetwork()。要了解有关此命令的更多信息,请参阅以下源链接上的 ACTION_CAPTIVE_PORTAL_SIGN_IN。

    来源:http://developer.android.com/reference/android/net/ConnectivityManager.html#ACTION_CAPTIVE_PORTAL_SIGN_IN

    http://developer.android.com/reference/android/net/CaptivePortal.html#ignoreNetwork()

    【讨论】: