API de Android para conectarse a la red Wifi
Estoy totalmente perdido en las versiones de las API de WiFi. Quiero conectarme a una red WiFi configurada programáticamente. Como se describe en esta pregunta: Conéctese a la red wifi de Android mediante programación
Desarrollo en Android 10 y quiero escribir un código que también sea compatible con versiones anteriores de Android.
En mi Android 10, el código descrito no funciona. ¿Qué código necesito para implementar la funcionalidad en Android 10?
¿Qué hago para escribir una aplicación que también se ejecute en mi otro teléfono con Android 9?
Saludos Jürgen
Respuestas
Aquí hay una solución que funciona desde Android 6 (nivel de API 23)
String AP_SSID = "YourWifiNetworkSSID";
String AP_PASSWORD = "YourWifiNetworkPassword";
wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + AP_SSID + "\""; // Please note the quotes. String should contain ssid in quotes
conf.preSharedKey = "\"" + AP_PASSWORD + "\"";
wifiManager.addNetwork(conf);
try {
List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
for (WifiConfiguration i : list) {
if (i.SSID != null && i.SSID.equals("\"" + AP_SSID + "\"")) {
wifiManager.disconnect();
wifiManager.enableNetwork(i.networkId, true);
wifiManager.reconnect();
break;
}
}
} catch (SecurityException e) {
Log.e(TAG, e.getMessage());
}
Desde Android Q, la conexión a la red Wifi ha cambiado mucho.
En primer lugar, el código que está utilizando o @matdev mencionado usa API public int addNetwork (WifiConfiguration config)de WifiManagerestá obsoleto en Android 10 y devolverá -1 como networkID.
Desde Android Q, se sugieren dos clases para la conexión Wifi. Pero cada uno de ellos tiene sus propias ventajas y desventajas.
1. WifiNetworkSpecifier
Un ejemplo de código de la biblioteca WifiUtil
WifiNetworkSpecifier.Builder wifiNetworkSpecifierBuilder = new WifiNetworkSpecifier.Builder()
.setSsid(scanResult.SSID)
.setBssid(MacAddress.fromString(scanResult.BSSID));
final String security = ConfigSecurities.getSecurity(scanResult);
ConfigSecurities.setupWifiNetworkSpecifierSecurities(wifiNetworkSpecifierBuilder, security, password);
NetworkRequest networkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(wifiNetworkSpecifierBuilder.build())
.build();
// not sure, if this is needed
if (networkCallback != null) {
connectivityManager.unregisterNetworkCallback(networkCallback);
}
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(@NonNull Network network) {
super.onAvailable(network);
wifiLog("AndroidQ+ connected to wifi ");
// bind so all api calls are performed over this new network
connectivityManager.bindProcessToNetwork(network);
}
@Override
public void onUnavailable() {
super.onUnavailable();
wifiLog("AndroidQ+ could not connect to wifi");
}
};
connectivityManager.requestNetwork(networkRequest, networkCallback);
Mi observación con esta implementación es: se parece más a una comunicación P2P, y en este momento otra aplicación del mismo dispositivo no puede usar Internet desde la red WiFi conectada
2. WifiNetworkSuggestion
Un ejemplo de código de developer.android.com
final WifiNetworkSuggestion suggestion1 =
new WifiNetworkSuggestion.Builder()
.setSsid("test111111")
.setIsAppInteractionRequired(true) // Optional (Needs location permission)
.build();
final WifiNetworkSuggestion suggestion2 =
new WifiNetworkSuggestion.Builder()
.setSsid("test222222")
.setWpa2Passphrase("test123456")
.setIsAppInteractionRequired(true) // Optional (Needs location permission)
.build();
final WifiNetworkSuggestion suggestion3 =
new WifiNetworkSuggestion.Builder()
.setSsid("test333333")
.setWpa3Passphrase("test6789")
.setIsAppInteractionRequired(true) // Optional (Needs location permission)
.build();
final PasspointConfiguration passpointConfig = new PasspointConfiguration();
// configure passpointConfig to include a valid Passpoint configuration
final WifiNetworkSuggestion suggestion4 =
new WifiNetworkSuggestion.Builder()
.setPasspointConfig(passpointConfig)
.setIsAppInteractionRequired(true) // Optional (Needs location permission)
.build();
final List<WifiNetworkSuggestion> suggestionsList =
new ArrayList<WifiNetworkSuggestion> {{
add(suggestion1);
add(suggestion2);
add(suggestion3);
add(suggestion4);
}};
final WifiManager wifiManager =
(WifiManager) context.getSystemService(Context.WIFI_SERVICE);
final int status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
// do error handling here…
}
// Optional (Wait for post connection broadcast to one of your suggestions)
final IntentFilter intentFilter =
new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals(
WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
return;
}
// do post connect processing here...
}
};
context.registerReceiver(broadcastReceiver, intentFilter);
Mi observación con la implementación mencionada anteriormente es que, cuando lo llama wifiManager.addNetworkSuggestions, devuelve éxito y muestra al usuario una notificación para la conexión. Si el usuario acepta, el dispositivo se conecta a la red WiFi y otra aplicación puede utilizar Internet. Pero si el usuario se desconecta de la red y wifiManager.addNetworkSuggestionsvuelve a llamar , devolverá un WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATEerror.
Parece que esta API solo proporciona una lista de sugerencias de redes donde el dispositivo puede conectarse automáticamente. Pero la conexión la determinará el sistema operativo.
Pero si realmente necesita una solución, utilice de forma indocumentada el escáner de código QR Wifi predeterminado de Android Source que puede detectar tanto los esquemas de código QR Zxing como DPP.
aquí hay un ejemplo de código:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_CODE_WIFI_QR_SCANNER && resultCode == RESULT_OK)
{
//WIFI Connection is Successful
}
else
{
//.......
}
}
@RequiresApi(api = Build.VERSION_CODES.Q)
private void startWifiQRCodeScanner(Context context)
{
final String INTENT_ACTION_WIFI_QR_SCANNER = "android.settings.WIFI_DPP_ENROLLEE_QR_CODE_SCANNER";
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if(wifiManager.isEasyConnectSupported())
{
final Intent intent = new Intent(INTENT_ACTION_WIFI_QR_SCANNER);
startActivityForResult(intent, REQUEST_CODE_WIFI_QR_SCANNER);
}
}