工作在安卓应用程序中,我需要通过编程连接没有互联网的WiFi设备。这是一个代码:
private void connectToWiFi(final String ssid, String password) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
final ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder request = new NetworkRequest.Builder();
request.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
request.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); // Internet not required
ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
String networkSSID = getNetworkSsid();
if (networkSSID.equals(ssid)) {
connectivityManager.bindProcessToNetwork(network);
}
}
@Override
public void onUnavailable() {
super.onUnavailable();
}
@Override
public void onLost(@NonNull Network network) {
super.onLost(network);
}
};
connectivityManager.registerNetworkCallback(request.build(), networkCallback);
WifiConfiguration config = new WifiConfiguration();
config.SSID = String.format("\"%s\"", ssid);
int netId = -1;
List<WifiConfiguration> apList = wifiManager.getConfiguredNetworks();
for (WifiConfiguration i : apList) {
if (i.SSID != null && i.SSID.equals("\"" + ssid + "\"")) {
netId = i.networkId;
}
}
// Add network in Saves network list if it is not available in list
if (netId == -1) {
if (TextUtils.isEmpty(password)) {
Log.d(TAG, "====== Connect to open network");
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
} else {
Log.d(TAG, "====== Connect to secure network");
config.preSharedKey = String.format("\"%s\"", password);
}
netId = wifiManager.addNetwork(config);
}
Log.d(TAG, "Connect to Network : " + netId);
wifiManager.enableNetwork(netId, true);
} else {
// For Android 10 and above
// WifiNetworkSpecifier code
}
}使用的权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />以上代码适用于提供互联网连接的网络。但是对于没有互联网连接的网络来说,它在大多数情况下都失败了。
当试图连接到没有internet访问权限的WiFi配置时,我们需要将应用程序的进程绑定到该网络,或者配置我们的HTTP客户端以使用该网络的套接字工厂,否则系统将与此WiFi网络断开连接。
根据本准则,bindProcessToNetwork已经被应用了。但是,无论在套接字工厂上使用bindToProcess() /路由通信,系统都是与网络断开连接的。它不允许与没有互联网的WiFi保持联系。令人惊讶的是,在限制网络连接之前,安卓从来没有考虑过IoT设备的用例。
当试图连接到我的应用程序或系统设置应用程序或任何其他应用程序添加的WiFi网络时,系统日志显示:
UID xxxxx does not have permission to update configuration
当应用程序试图连接具有互联网的设备时,即使该网络是由其他应用程序添加的,也不会发生相同的错误。
因此,该应用程序允许连接到以前的配置,尽管“权限不足”,流量是暂时通过这个网络路由。但几秒钟后,网络就断开了,系统试图与其他一些启用互联网的网络重新关联。
在Moto G5 Plus上进行测试,Android8.1.0,但我相信这是一个平台错误,而不是特定于设备。大多数情况下,这个bug是从Android 7或其他地方引入的,因为它以前就在工作。
我也曾报道过这里问题。在这个问题上还提供了示例应用程序。
这个问题有什么解决办法吗?有什么可供选择的付费支持Android吗?
提前谢谢。
发布于 2020-06-19 09:29:10
您提到的问题可能不是因为您在Issuetracker提供的代码。一旦我修复了我的设备(Android 9)中的问题,即使在完全撤消之后,我也无法复制错误。我甚至尝试过设备重新启动,应用程序重新安装,甚至工厂重置。尝尝这个。
发布于 2020-06-22 10:24:07
如果您的目标是在特定的网络中使用您的代码,那么您可以转到您的接入点接口,只需将DHCP设置设置为静态,并给设备一个适当的IP。
更多信息可以找到这里
现在,如果您针对的是无法访问其DHCP设置的网络,则可以根据该链接告诉您的设备保持与网络的连接,无论网络是否有互联网连接。
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) {
if (Build.VERSION.RELEASE.equalsIgnoreCase("6.0")) {
if (!Settings.System.canWrite(mActivity)) {
Intent goToSettings = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
goToSettings.setData(Uri.parse("package:" +
mActivity.getPackageName()));
mActivity.startActivity(goToSettings);
}
}
connectivityManager.bindProcessToNetwork(null);
if (mSsid.contains("my_iot_device-xxxxxxxxx"))
connectivityManager.bindProcessToNetwork(network);
else {
//This method was deprecated in API level 23
ConnectivityManager.setProcessDefaultNetwork(null);
if (mSsid.contains("my_iot_device-xxxxxxxxx"))
ConnectivityManager.setProcessDefaultNetwork(network);
}
connectivityManager.unregisterNetworkCallback(this);
}
}
});
}另外,有时保持无线无线收音机保持清醒是很好的,所以你需要使用WiFiLock来保持它。
//Create a wifi manager instance first
WifiManager mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
//and then create your wifiLock
WifiManager.WifiLock mWifiLock = mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "wifiLock");
if(!mWifiLock.isHeld())
mWifiLock.acquire();以后如果你想实现的话
if(mWifiLock.isHeld())
mWifiLock.release();这个代码帮助我保持与我的网络的连接,即使它没有互联网接入。
发布于 2022-11-09 23:20:55
取代:
connectivityManager.registerNetworkCallback 链接使用
connectivityManager.requestNetwork 链接requestNetwork上的相关文档来自上面的链接:
只要此请求尚未完成,平台将尝试维护维护与此请求匹配的最佳网络,同时尽可能尝试将请求匹配到更好的网络。
注意,上述文档不包括在registerNetworkCallback**.**中。
Android连接堆栈将拆除未使用的网络。通过requestNetwork对网络的请求数量进行跟踪。因此,就连接堆栈而言,您所请求的Wi网络没有被请求,因此可以被拆除。
这不适用于默认网络,但是只有具有互联网能力的网络才有资格成为默认网络,而在您的情况下不适用。
https://stackoverflow.com/questions/62320720
复制相似问题