Android 如何使用NetworkRequest.Builder()指定wifi网络。setNetworkSpecifier(字符串)

Android 如何使用NetworkRequest.Builder()指定wifi网络。setNetworkSpecifier(字符串),android,networking,android-wifi,captiveportal,Android,Networking,Android Wifi,Captiveportal,我正在寻找一种方法,让安卓5.0平板电脑连接到一个内联网,而内联网由于安全原因没有互联网连接 问题在于谷歌自4.4/5.0以来在安卓系统中构建的专属门户保护。 进行呼叫以检查互联网连接,当此呼叫失败时,wifi网络被标记为不工作并被避免。很蹩脚 其他人也遇到了同样的问题,一些人建议使用android 5中引入的新API,请参见: 关于这一点的文件非常模糊: NetworkRequest.Builder.setNetworkSpecifier(String networkSpecifier)

我正在寻找一种方法,让安卓5.0平板电脑连接到一个内联网,而内联网由于安全原因没有互联网连接

问题在于谷歌自4.4/5.0以来在安卓系统中构建的专属门户保护。 进行呼叫以检查互联网连接,当此呼叫失败时,wifi网络被标记为不工作并被避免。很蹩脚

其他人也遇到了同样的问题,一些人建议使用android 5中引入的新API,请参见:

关于这一点的文件非常模糊:

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);
    }
}
private void connect(字符串ssid,上下文){
Log.i(标记“try connect to!”+ssid);
ConnectivityManager cm=(ConnectivityManager)context.getSystemService(context.CONNECTIVITY_服务);
NetworkRequest nr=新建NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT\u WIFI)。
removeCapability(NetworkCapabilities.NET\u CAPABILITY\u TRUSTED)。
可移除性(NetworkCapabilities.NET\u能力\u互联网
setNetworkSpecifier(ssid)。/=Build.VERSION\u code.LOLLIPOP){
Log.i(标记“onAvailable”+network.toString()+“”+network.getClass().getName());
}
}
@凌驾
容量更改后的公共void(网络、网络能力、网络能力){
试一试{
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.LOLLIPOP){
Log.i(标记“onCapabilitiesChanged”+networkCapabilities.getLinkDownstreamBandwidthKbps());
}
}捕获(例外e){
e、 printStackTrace();
}
}
@凌驾
公共void onlinkproperties已更改(网络、LinkProperties LinkProperties){
试一试{
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.LOLLIPOP){
i(标记“onLinkPropertiesChanged”+linkProperties.getInterfaceName());
}
}捕获(例外e){
e、 printStackTrace();
}
}
};
Log.i(标签“requestNetwork”);
//请求网络(nr,回调);
cm.registerNetworkCallback(nr,callback);
}
}

首先欺骗始终是一种选择,只是要求人们更改手机设置以使用网络。骗局是这样的。 Wifi->高级->未选中

然而,我相信这不是你想要的答案。所以我为你做了一些研究,找到了需要的东西。您需要调用命令ignoreNetwork()。要了解有关此命令的更多信息,请在下面的源链接上登录

资料来源:


我在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
        }
    }
}
void-inspectNetworks(){
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.LOLLIPOP){
ConnectivityManager connectivity=(ConnectivityManager)getSystemService(Context.connectivity_服务);
Network[]ns=connectivity.getAllNetworks();
用于(网络n:ns){
NetworkCapabilities c=连接性。getNetworkCapabilities(n);

Log.i(TAG,“inspectNetworks:network=“+n+”capabilities=“+c”);//你找到解决方案了吗?没有,仍然没有找到解决方法。有一些好消息(关于Android Q)-