问题
I had this function to connect in Wifi network, below Android 10 it works fine, but when I tried on Android 10, I had a successful connection but WITHOUT internet, I knew it's a bug in Android 10 but I found this application which can connect to wifi from Android 10 with no problem. I'm blocked for days.
My function :
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);
}
}
回答1:
In case if you want to connect to WiFi with INTERNET, you should use this kind of NetworkRequest:
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(wifiNetworkSpecifier)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.build();
Also, you need specify default route for your process to make requests to connected WiFi AP permanently. Just add call of next method to your NetworkCallback under onAvaliable like this:
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);
}
}
Don't forget disconnect from the bound network:
connectivityManager.unregisterNetworkCallback(networkCallback);
Finally, you can find best practice in different libraries like WifiUtils.
回答2:
If you have root access (adb root):
Manually connect to the Wifi Network of your choosing.
Pull these ADB files:
adb pull /data/misc/wifi/WifiConfigStore.xml
adb pull /data/misc/wifi/WifiConfigStore.xml.encrypted-checksum
- Save in a folder that would designate the Wifi Network:
Ex: GarageWifi
Ex: BusinessWifi
Copy to location of your choosing. Don't change the names of the files you pulled.
- Whenever you want to connect to a desired wifi network:
adb push <location>\WifiConfigStore.xml /data/misc/wifi/
adb push <location>\WifiConfigStore.xml.encrypted-checksum /data/misc/wifi/
adb reboot
回答3:
You can try wifisuggestion api, I'm able to connect using them.
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);
}
回答4:
So, the solution for me is compile your app with targetSdkVersion 28. and for connection to wifi use this function
connectToWifi(String ssid, String key)
it's just a workaround for the moment, waiting Google to publish a fix for this bug, for more information the issue reported to 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();
}
来源:https://stackoverflow.com/questions/63124728/connect-to-wifi-in-android-q-programmatically