我正在开发基于Raspberry Pi的IoT设备,该设备托管自己的WiFi AP(无互联网),并且即使启用了移动数据,也已经成功地按照this Android Developers blog post from 2016连接到该设备并从我的Android应用路由到该设备的流量(即通过Network#getSocketFactory
)。 (即,我没有在此问题中报告此问题:Send request over WiFi (without connection) even if Mobile data is ON (with connection) on Android M)
现在的问题是,我的Android 10设备(一个Google Pixel)会在几分钟后自动从网络断开连接并切换到我的家庭WiFi网络(带有互联网)。这是在前台的应用程序,并通过活动的Web套接字连接到在Pi上运行的服务器端应用程序。
我可以通过侦听应用程序中的网络状态变化并通过WifiManager#enableNetwork
强制重新连接到我的物联网网络来解决此问题,但这似乎是一个棘手的解决方案,并且连接仍然会中断,从而导致糟糕的用户体验。
[另一个我以为我要使用WifiManager#enableNetwork
来禁用所有其他已配置的WiFi网络,从而阻止手机连接到它们。但是该文档指出不允许禁用其他应用程序创建的网络。
[保持没有互联网访问的IoT WiFi网络连接似乎是Google知道(或知道)的Android应用程序的合理用例,但我正在努力拼凑当前的最佳做法,以在2020年做到这一点。我想知道是否可以通过更新的WifiManager#disableNetwork
实现。但是,这些听起来对应用程序开发人员的限制更大,并且不对将要加入的WiFi网络提供任何保证。
您可以将Android绑定到与其连接的WiFi接入点。
这可以使用WifiManager#disableNetwork
的WiFi suggestion APIs:
ConnectivityManager
这也将防止Android将当前的连接从没有互联网的WiFi AP切换到移动数据
转到其底部。对于我来说,适用于Android 10的解决方案是:bindProcessToNetwork(network)
即使用final ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder = new NetworkRequest.Builder();
//set the transport type to WIFI
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
try {
manager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
manager.bindProcessToNetwork(network);
} else {
ConnectivityManager.setProcessDefaultNetwork(network);
}
manager.unregisterNetworkCallback(this);
}
});
} catch (SecurityException e) {
Log.e(TAG, e.getMessage());
}
和https://stackoverflow.com/a/58770341/1405990:
WifiNetworkSpecifier
这将显示一个系统对话框,用户可以从中最终选择IoT wifi网络进行连接。
使Android保持与网络的连接的关键是不要从ConnectivityManager#requestNetwork
注销网络回调。除非您这样做,否则Android 10不会自动切换回可以上网的状态。
由于对话框标题不太清楚,并且由于显示匹配的WiFi网络时出现莫名其妙的延迟(在旧扫描结果中已经可见),因此用户体验不佳。但是现在至少可以与Android 10上的IoT设备保持持久连接。