以编程方式连接到 Android Q 中的 Wifi
Connect to Wifi in Android Q programmatically
我有这个功能可以连接到 Wifi 网络,低于 Android 10 它工作正常,但是当我尝试 Android 10 时,我连接成功但是 WITHOUT互联网,我知道它是a bug in Android 10 but I found this application,它可以从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);
}
}
如果你想通过互联网连接到 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();
此外,您需要为您的进程指定默认路由,以永久向连接的 WiFi AP 发出请求。只需将下一个方法的调用添加到 onAvaliable 下的 NetworkCallback,如下所示:
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
createNetworkRoute(network, connectivityManager);
}
};
if (connectivityManager!= null) connectivityManager.requestNetwork(request, networkCallback);
.
@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);
}
}
不要忘记断开与绑定网络的连接:
connectivityManager.unregisterNetworkCallback(networkCallback);
最后,您可以在不同的库中找到最佳实践,例如 WifiUtils。
如果您有 root 访问权限 (adb root):
手动连接到您选择的 Wifi 网络。
拉取这些 ADB 文件:
adb pull /data/misc/wifi/WifiConfigStore.xml
adb pull /data/misc/wifi/WifiConfigStore.xml.encrypted-checksum
- 保存在指定 Wifi 网络的文件夹中:
Ex: GarageWifi
Ex: BusinessWifi
复制到您选择的位置。 不要更改您提取的文件的名称。
- 每当您想连接到所需的 wifi 网络时:
adb push <location>\WifiConfigStore.xml /data/misc/wifi/
adb push <location>\WifiConfigStore.xml.encrypted-checksum /data/misc/wifi/
adb reboot
你可以试试wifisuggestionapi,我可以用它们连接。
final WifiNetworkSuggestion suggestion1 =
new WifiNetworkSuggestion.Builder()
.setSsid("YOUR_SSID")
.setWpa2Passphrase("YOUR_PRE_SHARED_KEY")
.build();
final List<WifiNetworkSuggestion> suggestionsList =
new ArrayList<WifiNetworkSuggestion>();
suggestionsList.add(suggestion1);
WifiManager wifiManager =
(WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
int status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status == 0 ){
Toast.makeText(this,"PSK network added",Toast.LENGTH_LONG).show();
Log.i(TAG, "PSK network added: "+status);
}else {
Toast.makeText(this,"PSK network not added",Toast.LENGTH_LONG).show();
Log.i(TAG, "PSK network not added: "+status);
}
所以,我的解决方案是使用 targetSdkVersion 28 编译您的应用程序。
并连接到 wifi 使用此功能
connectToWifi(String ssid, String key)
目前只是一种解决方法,等待 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();
}
到目前为止,在我测试过的大多数设备上,什么对我有用,有一个后备选项至少可以阻止可怕的 'looping request' 并允许成功的手动连接
下面的代码是用Kotlin写的,如果需要请google如何转换成Java
创建一个 NetworkCallback,它是 API >= 29 所必需的(之前它不是必需的,但可以使用)
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
}
}
按如下方式连接到网络:
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)
如 here by Google 所述,一些 OEM Rom 不是 'holding on to the request',因此连接立即断开。 OnePlus 已经在他们后来的一些型号中解决了这个问题,但不是全部。对于某些 Android 构建中的某些 phone 模型,此错误将持续存在,因此需要成功的回退(即手动连接,没有网络中断)。没有已知的解决方法可用,但如果找到我会在此处更新它作为一个选项。
要删除网络,请执行以下操作:
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)
请记住,自动连接允许自动和手动断开连接。手动连接(例如建议的 OnePlus 设备回退)不允许自动断开连接。这也需要在应用程序中处理,以便在涉及物联网设备时实现更好的用户体验设计。
一些额外的小提示和信息:
现在系统对话框打开,应用程序分别调用 onPause 和 onResume。这影响了我关于自动连接到物联网设备的逻辑。在某些情况下,onResume 在网络回调完成之前被调用。
关于测试,我还不能通过使用浓缩咖啡来绕过对话框,它可能会阻止一些在 API 29 之前工作的测试。它可能是可能使用其他框架,如 uiautomator。在我的例子中,我调整了测试直到对话框显示,然后 运行 进一步测试。
使用 Intents.init() 不起作用。
onUnavailable 在找到网络但用户取消时调用。当找不到网络时不会调用它,或者如果用户在找到网络之前取消对话,在这种情况下不会调用其他方法,请使用 onResume 来捕获它。
当它在 OnePlus 上失败时,它分别调用 onAvailable() -> onCapabilitiesChanged() -> onBlockedStatusChanged (blocked: false) -> onCapabilitiesChanged() -> onLost()
removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 不会帮助保持 OnePlus 上的连接,如所述 here
如所述here
设置 Bssid 无助于保持 OnePlus 上的连接
google 帮不上忙,他们说这不是他们能控制的 here
-
当GPS关闭时,网络的SSID名称不可用
如果对话框多次出现,请检查您自己的 activity 生命周期,在我的例子中,一些模型在收到网络回调之前调用了 onResume。
手动连接到没有互联网功能的网络需要用户确认以保持连接(有时以对话框或通知的形式),如果忽略,系统将很快断开网络连接之后
测试的设备列表:
- Google Pixel 2 - 未发现问题
- 三星 S10 SM-G970F - 未发现问题
- 三星 S9 SM-G960F - 未发现问题
- One Plus A5000 (OxegenOS 10.0.1) - 自动连接的主要问题
- HTC One M8 (LineageOS 17.1) - 未发现问题
- 小米 Note 10 - 断开连接问题(已修复,参见代码示例)
- Samsung A50 - 连接成功后重复出现对话框(有时)
- Huawei Mate Pro 20 - 连接成功后重复出现对话框(有时)
- Huawei P40 Lite - 不调用 onLost()
- CAT S62 Pro - 未发现问题
- 索尼 Xperia SZ2 - 未发现问题
- 三星 Note10 - 未发现问题
从 Android 10 开始,我必须使用以下代码连接到特定的 wifi 网络。
private ConnectivityManager mConnectivityManager;
@Override
public void onCreate(@Nullable Bundle savedInstanceState){
// instantiate the connectivity manager
mConnectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
}
public void connect(String ssid, String password) {
NetworkSpecifier networkSpecifier = new WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setWpa2Passphrase(password)
.setIsHiddenSsid(true) //specify if the network does not broadcast itself and OS must perform a forced scan in order to connect
.build();
NetworkRequest networkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(networkSpecifier)
.build();
mConnectivityManager.requestNetwork(networkRequest, mNetworkCallback);
}
public void disconnectFromNetwork(){
//Unregistering network callback instance supplied to requestNetwork call disconnects phone from the connected network
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
}
private ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager.NetworkCallback(){
@Override
public void onAvailable(@NonNull Network network) {
super.onAvailable(network);
//phone is connected to wifi network
}
@Override
public void onLosing(@NonNull Network network, int maxMsToLive) {
super.onLosing(network, maxMsToLive);
//phone is about to lose connection to network
}
@Override
public void onLost(@NonNull Network network) {
super.onLost(network);
//phone lost connection to network
}
@Override
public void onUnavailable() {
super.onUnavailable();
//user cancelled wifi connection
}
};
参考资料:
https://anutoshdatta.medium.com/new-wifi-apis-on-android-10-481c525108b7
https://developer.android.com/guide/topics/connectivity/wifi-suggest
我也遇到了同样的问题,3个月了也解决不了。但我找到了一个很棒的解决方案。
startActivity(new Intent("android.settings.panel.action.INTERNET_CONNECTIVITY"))
只需添加这些行而不是从应用程序连接到 wifi,这将提示用户 select wifi 并连接,一旦用户这样做,它就会连接到 wifi 并且它也会也会有互联网。
仅从应用程序连接到 wifi 将无法访问互联网。这样做,这是最好的解决方案。
我有这个功能可以连接到 Wifi 网络,低于 Android 10 它工作正常,但是当我尝试 Android 10 时,我连接成功但是 WITHOUT互联网,我知道它是a bug in Android 10 but I found this application,它可以从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);
}
}
如果你想通过互联网连接到 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();
此外,您需要为您的进程指定默认路由,以永久向连接的 WiFi AP 发出请求。只需将下一个方法的调用添加到 onAvaliable 下的 NetworkCallback,如下所示:
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
createNetworkRoute(network, connectivityManager);
}
};
if (connectivityManager!= null) connectivityManager.requestNetwork(request, networkCallback);
.
@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);
}
}
不要忘记断开与绑定网络的连接:
connectivityManager.unregisterNetworkCallback(networkCallback);
最后,您可以在不同的库中找到最佳实践,例如 WifiUtils。
如果您有 root 访问权限 (adb root):
手动连接到您选择的 Wifi 网络。
拉取这些 ADB 文件:
adb pull /data/misc/wifi/WifiConfigStore.xml
adb pull /data/misc/wifi/WifiConfigStore.xml.encrypted-checksum
- 保存在指定 Wifi 网络的文件夹中:
Ex: GarageWifi
Ex: BusinessWifi
复制到您选择的位置。 不要更改您提取的文件的名称。
- 每当您想连接到所需的 wifi 网络时:
adb push <location>\WifiConfigStore.xml /data/misc/wifi/
adb push <location>\WifiConfigStore.xml.encrypted-checksum /data/misc/wifi/
adb reboot
你可以试试wifisuggestionapi,我可以用它们连接。
final WifiNetworkSuggestion suggestion1 =
new WifiNetworkSuggestion.Builder()
.setSsid("YOUR_SSID")
.setWpa2Passphrase("YOUR_PRE_SHARED_KEY")
.build();
final List<WifiNetworkSuggestion> suggestionsList =
new ArrayList<WifiNetworkSuggestion>();
suggestionsList.add(suggestion1);
WifiManager wifiManager =
(WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
int status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status == 0 ){
Toast.makeText(this,"PSK network added",Toast.LENGTH_LONG).show();
Log.i(TAG, "PSK network added: "+status);
}else {
Toast.makeText(this,"PSK network not added",Toast.LENGTH_LONG).show();
Log.i(TAG, "PSK network not added: "+status);
}
所以,我的解决方案是使用 targetSdkVersion 28 编译您的应用程序。 并连接到 wifi 使用此功能
connectToWifi(String ssid, String key)
目前只是一种解决方法,等待 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();
}
到目前为止,在我测试过的大多数设备上,什么对我有用,有一个后备选项至少可以阻止可怕的 'looping request' 并允许成功的手动连接
下面的代码是用Kotlin写的,如果需要请google如何转换成Java
创建一个 NetworkCallback,它是 API >= 29 所必需的(之前它不是必需的,但可以使用)
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
}
}
按如下方式连接到网络:
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)
如 here by Google 所述,一些 OEM Rom 不是 'holding on to the request',因此连接立即断开。 OnePlus 已经在他们后来的一些型号中解决了这个问题,但不是全部。对于某些 Android 构建中的某些 phone 模型,此错误将持续存在,因此需要成功的回退(即手动连接,没有网络中断)。没有已知的解决方法可用,但如果找到我会在此处更新它作为一个选项。
要删除网络,请执行以下操作:
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)
请记住,自动连接允许自动和手动断开连接。手动连接(例如建议的 OnePlus 设备回退)不允许自动断开连接。这也需要在应用程序中处理,以便在涉及物联网设备时实现更好的用户体验设计。
一些额外的小提示和信息:
现在系统对话框打开,应用程序分别调用 onPause 和 onResume。这影响了我关于自动连接到物联网设备的逻辑。在某些情况下,onResume 在网络回调完成之前被调用。
关于测试,我还不能通过使用浓缩咖啡来绕过对话框,它可能会阻止一些在 API 29 之前工作的测试。它可能是可能使用其他框架,如 uiautomator。在我的例子中,我调整了测试直到对话框显示,然后 运行 进一步测试。 使用 Intents.init() 不起作用。
onUnavailable 在找到网络但用户取消时调用。当找不到网络时不会调用它,或者如果用户在找到网络之前取消对话,在这种情况下不会调用其他方法,请使用 onResume 来捕获它。
当它在 OnePlus 上失败时,它分别调用 onAvailable() -> onCapabilitiesChanged() -> onBlockedStatusChanged (blocked: false) -> onCapabilitiesChanged() -> onLost()
removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 不会帮助保持 OnePlus 上的连接,如所述 here
如所述here
设置 Bssid 无助于保持 OnePlus 上的连接google 帮不上忙,他们说这不是他们能控制的 here
当GPS关闭时,网络的SSID名称不可用
如果对话框多次出现,请检查您自己的 activity 生命周期,在我的例子中,一些模型在收到网络回调之前调用了 onResume。
手动连接到没有互联网功能的网络需要用户确认以保持连接(有时以对话框或通知的形式),如果忽略,系统将很快断开网络连接之后
测试的设备列表:
- Google Pixel 2 - 未发现问题
- 三星 S10 SM-G970F - 未发现问题
- 三星 S9 SM-G960F - 未发现问题
- One Plus A5000 (OxegenOS 10.0.1) - 自动连接的主要问题
- HTC One M8 (LineageOS 17.1) - 未发现问题
- 小米 Note 10 - 断开连接问题(已修复,参见代码示例)
- Samsung A50 - 连接成功后重复出现对话框(有时)
- Huawei Mate Pro 20 - 连接成功后重复出现对话框(有时)
- Huawei P40 Lite - 不调用 onLost()
- CAT S62 Pro - 未发现问题
- 索尼 Xperia SZ2 - 未发现问题
- 三星 Note10 - 未发现问题
从 Android 10 开始,我必须使用以下代码连接到特定的 wifi 网络。
private ConnectivityManager mConnectivityManager;
@Override
public void onCreate(@Nullable Bundle savedInstanceState){
// instantiate the connectivity manager
mConnectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
}
public void connect(String ssid, String password) {
NetworkSpecifier networkSpecifier = new WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setWpa2Passphrase(password)
.setIsHiddenSsid(true) //specify if the network does not broadcast itself and OS must perform a forced scan in order to connect
.build();
NetworkRequest networkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(networkSpecifier)
.build();
mConnectivityManager.requestNetwork(networkRequest, mNetworkCallback);
}
public void disconnectFromNetwork(){
//Unregistering network callback instance supplied to requestNetwork call disconnects phone from the connected network
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
}
private ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager.NetworkCallback(){
@Override
public void onAvailable(@NonNull Network network) {
super.onAvailable(network);
//phone is connected to wifi network
}
@Override
public void onLosing(@NonNull Network network, int maxMsToLive) {
super.onLosing(network, maxMsToLive);
//phone is about to lose connection to network
}
@Override
public void onLost(@NonNull Network network) {
super.onLost(network);
//phone lost connection to network
}
@Override
public void onUnavailable() {
super.onUnavailable();
//user cancelled wifi connection
}
};
参考资料: https://anutoshdatta.medium.com/new-wifi-apis-on-android-10-481c525108b7 https://developer.android.com/guide/topics/connectivity/wifi-suggest
我也遇到了同样的问题,3个月了也解决不了。但我找到了一个很棒的解决方案。
startActivity(new Intent("android.settings.panel.action.INTERNET_CONNECTIVITY"))
只需添加这些行而不是从应用程序连接到 wifi,这将提示用户 select wifi 并连接,一旦用户这样做,它就会连接到 wifi 并且它也会也会有互联网。
仅从应用程序连接到 wifi 将无法访问互联网。这样做,这是最好的解决方案。