Eup*_*r08 15 android wifi android-wifi android-10.0
我有这个功能可以在 Wifi 网络中连接,在 Android 10 以下它工作正常,但是当我在 Android 10 上尝试时,我成功连接但没有互联网,我知道这是Android 10 中的一个错误,但我发现这个应用程序可以连接从 Android 10 连接到 wifi 没有问题。我被屏蔽了好几天。
我的功能:
private void connectToWifi(String ssid, String password)
{
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
try {
Log.e(TAG,"connection wifi pre Q");
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = "\"" + ssid + "\"";
wifiConfig.preSharedKey = "\"" + password + "\"";
int netId = wifiManager.addNetwork(wifiConfig);
wifiManager.disconnect();
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();
} catch ( Exception e) {
e.printStackTrace();
}
} else {
Log.e(TAG,"connection wifi Q");
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder()
.setSsid( ssid )
.setWpa2Passphrase(password)
.build();
NetworkRequest networkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(wifiNetworkSpecifier)
.build();
connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
super.onAvailable(network);
connectivityManager.bindProcessToNetwork(network);
Log.e(TAG,"onAvailable");
}
@Override
public void onLosing(@NonNull Network network, int maxMsToLive) {
super.onLosing(network, maxMsToLive);
Log.e(TAG,"onLosing");
}
@Override
public void onLost(Network network) {
super.onLost(network);
Log.e(TAG, "losing active connection");
}
@Override
public void onUnavailable() {
super.onUnavailable();
Log.e(TAG,"onUnavailable");
}
};
connectivityManager.requestNetwork(networkRequest,networkCallback);
}
}
Run Code Online (Sandbox Code Playgroud)
Let*_*aus 10
到目前为止,在我测试过的大多数设备上,什么对我有用,有一个回退选项,至少可以停止可怕的“循环请求”并允许成功的手动连接
下面的代码是用 Kotlin 编写的,如果需要,请谷歌如何转换到 Java。
创建API >= 29 所需的NetworkCallback(之前不需要但可以使用)
val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// To make sure that requests don't go over mobile data
connectivityManager.bindProcessToNetwork(network)
} else {
connectivityManager.setProcessDefaultNetwork(network)
}
}
override fun onLost(network: Network) {
super.onLost(network)
// This is to stop the looping request for OnePlus & Xiaomi models
connectivityManager.bindProcessToNetwork(null)
connectivityManager.unregisterNetworkCallback(networkCallback)
// Here you can have a fallback option to show a 'Please connect manually' page with an Intent to the Wifi settings
}
}
Run Code Online (Sandbox Code Playgroud)
连接到网络如下:
val wifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setWpa2Passphrase(pass)
.build()
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
// Add the below 2 lines if the network should have internet capabilities.
// Adding/removing other capabilities has made no known difference so far
// .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
// .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.setNetworkSpecifier(wifiNetworkSpecifier)
.build()
connectivityManager.requestNetwork(networkRequest, networkCallback)
Run Code Online (Sandbox Code Playgroud)
正如谷歌在此处所述,一些 OEM Roms 没有“坚持请求”,因此连接立即断开。OnePlus 在其后期的一些型号中解决了这个问题,但不是全部。对于某些 Android 版本上的某些手机型号,此错误将持续存在,因此需要成功回退(即没有网络中断的手动连接)。没有已知的解决方法可用,但如果找到,我会在这里更新它作为一个选项。
要删除网络,请执行以下操作:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//This is required for Xiaomi models for disconnecting
connectivityManager.bindProcessToNetwork(null)
} else {
connectivityManager.setProcessDefaultNetwork(null)
}
connectivityManager.unregisterNetworkCallback(it)
Run Code Online (Sandbox Code Playgroud)
请记住,自动连接允许自动和手动断开连接。手动连接(例如建议的 OnePlus 设备后备)不允许自动断开连接。当涉及到物联网设备时,这也需要在应用程序中处理以获得更好的用户体验设计。
一些额外的小提示和信息:
现在系统对话框打开,应用程序分别调用 onPause 和 onResume。这影响了我关于自动连接到物联网设备的逻辑。在某些情况下,onResume 在网络回调完成之前被调用。
关于测试,我还不能仅使用 espresso 来绕过对话框,它可能会阻止一些在 API 29 之前工作的测试。使用其他框架(例如 uiautomator)可能是可能的。在我的情况下,我调整了测试,直到对话框显示,然后运行进一步的测试。使用 Intents.init() 不起作用。
当找到网络时调用 onUnavailable,但用户取消。当未找到网络或用户在找到网络之前取消对话时不会调用它,在这种情况下没有调用其他方法,请使用 onResume 来捕获它。
当它在 OnePlus 上失败时,它分别调用 onAvailable() -> onCapabilitiesChanged() -> onBlockedStatusChanged (blocked: false) -> onCapabilitiesChanged() -> onLost()
removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)不会帮助保持上万普拉斯的连接,说明这里
设置BSSID不会帮助保持上万普拉斯的连接,说明这里
谷歌不能帮助下,他们都表示这是他们手中的出来这里
GPS关闭时,网络的SSID名称不可用
如果对话框多次出现,请检查您自己的活动生命周期,在我的情况下,某些模型在收到网络回调之前调用了 onResume。
手动连接到没有互联网功能的网络需要用户确认以保持连接(有时以对话或通知的形式),如果忽略,系统将在不久之后与网络断开连接
测试设备列表:
如果您想通过 INTERNET 连接到 WiFi,您应该使用这种NetworkRequest:
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(wifiNetworkSpecifier)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.build();
Run Code Online (Sandbox Code Playgroud)
此外,您需要为您的进程指定默认路由,以永久向连接的 WiFi AP 发出请求。只需将 next 方法的调用添加到onAvaliable下的NetworkCallback 中,如下所示:
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
createNetworkRoute(network, connectivityManager);
}
};
if (connectivityManager!= null) connectivityManager.requestNetwork(request, networkCallback);
Run Code Online (Sandbox Code Playgroud)
.
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private static void createNetworkRoute(Network network, ConnectivityManager connectivityManager) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManager.bindProcessToNetwork(network);
} else {
ConnectivityManager.setProcessDefaultNetwork(network);
}
}
Run Code Online (Sandbox Code Playgroud)
不要忘记断开与绑定网络的连接:
connectivityManager.unregisterNetworkCallback(networkCallback);
Run Code Online (Sandbox Code Playgroud)
最后,您可以在WifiUtils等不同的库中找到最佳实践。
所以,对我来说,解决方案是使用targetSdkVersion 28编译您的应用程序。要连接到 wifi,请使用此功能
connectToWifi(String ssid, String key)
Run Code Online (Sandbox Code Playgroud)
这只是暂时的解决方法,等待 Google 发布此错误的修复程序,有关向 Google 报告的问题的更多信息:issuetracker.google.com/issues/138335744
public void connectToWifi(String ssid, String key) {
Log.e(TAG, "connection wifi pre Q");
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = "\"" + ssid + "\"";
wifiConfig.preSharedKey = "\"" + key + "\"";
int netId = wifiManager.addNetwork(wifiConfig);
if (netId == -1) netId = getExistingNetworkId(wifiConfig.SSID);
wifiManager.disconnect();
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7258 次 |
最近记录: |