我正在开发一个安卓应用程序,它需要通过WiFi网络进行通信,而该网络不会有任何互联网接入。问题是,即使连接了WiFi,当无线网络上没有连接互联网时,安卓选择使用蜂窝/移动数据。
我读过很多关于这个问题的文章,其中很多涉及到设备的根,但这在生产应用程序中是不可能的(生根设备是,而不是)。其他解决方案(如下面的代码)建议使用bindProcessToNetwork()
,它在我的索尼Z2上工作得很好,但在我测试过的其他设备上却不起作用(全部运行6.0.1)
private void bindToNetwork() {
final ConnectivityManager connectivityManager = (ConnectivityManager) mActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder = new NetworkRequest.Builder();
//set the transport type do WIFI
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
connectivityManager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManager.bindProcessToNetwork(null);
if (barCodeData.getSsid().contains("ap-name")) {
connectivityManager.bindProcessToNetwork(network);
}
} else {
//This method was deprecated in API level 23
ConnectivityManager.setProcessDefaultNetwork(null);
if (barCodeData.getSsid().contains("ap-name")) {
ConnectivityManager.setProcessDefaultNetwork(network);
}
}
connectivityManager.unregisterNetworkCallback(this);
}
});
}
}
发布于 2017-03-03 04:07:54
您可以通过将captive_portal_detection_enabled设置为0 (false)来解决这个问题。
实际上,在默认情况下,每次连接到wifi时,FW都会对服务器(通常是google)进行测试,以确定它是否是专用wifi (需要登录)。因此,如果您的wifi没有连接到谷歌,这个检查将失败。在那之后,设备知道wifi没有互联网连接,而且根本就不会自动连接到它。
将此设置设置为0将避免此检查。
编程:Settings.Global.putInt(getContentResolver(), Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 0);
编辑:您可能需要直接使用字符串"captive_portal_detection_enabled“,而不是依赖于Android版本不可见的常量。
发布于 2017-03-09 11:13:44
您需要在设置中禁用移动数据(不确定,这是否可以通过编程方式完成,这可能是一个可能的选项)--或者取出USIM;
否则,通常的行为是,它将始终回到最佳可用连接(而与internet网关的连接可能是首选的,因为它被大多数应用程序使用)。
还可以看到这个回答。
发布于 2018-07-22 23:24:55
您在正确的道路上,解决方案确实是使用ConnectivityManager.bindProcessToNetwork(network)。这一信息发布在本文将应用程序连接到Wi设备的Android开发者博客上。
查看您的代码,这个barCodeData.getSsid()
看起来没有得到当前连接的wifi网络的SSID。如果是这样的话,您的代码将永远无法成功地绑定到网络。
尝试替换您的if语句
if (barCodeData.getSsid().contains("ap-name"))
使用
if (getNetworkSsid(context).equals("ap-name"))
在kotlin中检索连接wifi网络的SSID的辅助方法
private fun getNetworkSsid(context: Context?): String {
// WiFiManager must use application context (not activity context) otherwise a memory leak can occur
val mWifiManager = context?.applicationContext?.getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiInfo: WifiInfo? = mWifiManager.connectionInfo
if (wifiInfo?.supplicantState == SupplicantState.COMPLETED) {
return wifiInfo.ssid.removeSurrounding("\"")
}
return ""
}
如果仍然不能工作,请遵循我的完全解决方案,我使用了相同的方法,但有一些额外的检查。我在Android版本5.1.1、6.0、6.0.1、7.1.1和8.1.0中测试了它。
https://stackoverflow.com/questions/42492136
复制相似问题