Je travaille sur une application IoT dans laquelle il existe un processus d'intégration dans lequel l'utilisateur se connecte à un point d'accès n'ayant pas de connexion Internet, configure le périphérique, puis se connecte à son réseau Wifi domestique.
Les appareils Android 8 ont causé des problèmes, en se déconnectant du point d'accès et en se reconnectant à un réseau préalablement configuré. Je suppose que cela est lié à la mise à jour de la connectivité introduite dans Android 8, de la section Connectivité transparente dans ce lien :
Sur les appareils compatibles, l’activation automatique du Wi-Fi lorsqu’un niveau élevé réseau de qualité enregistrée est à proximité.
Ma question est de savoir comment désactiver ce comportement car je dois rester connecté au point d'accès, sans connexion Internet, et terminer le processus d'embarquement.
J'ai eu le même problème. Ce que j'ai fait est d'ajouter une étape au processus d'embarquement dans laquelle j'invite l'utilisateur à accéder à ses paramètres, à ajouter manuellement ce réseau sans données et à accepter la fenêtre contextuelle affichée par le système.
Je n'ai pas encore trouvé de solution réelle… .. Cependant, j'ai vu une application appelée eWeLink où ils parviennent à le faire, mais ce n'est pas un projet open source.
Je voulais juste ajouter un peu à la discussion. J'utilise bindProcessToNetwork depuis un moment et cela corrige la perte de WiFi lorsqu'il est connecté à un réseau sans réseau, comme décrit par Shawn Chen. C'est une solution lourde qui rend difficile l'utilisation du réseau mobile en même temps. Cependant, la couche de routage est plutôt cassée sur Android quelque part vers 6 où ils ont commencé à forcer la demande sur mobile alors que la table de routage indique le périphérique wifi.
Quoi qu'il en soit, vous pouvez réellement relier au niveau de la socket que je décris ci-dessous. Cela peut aider lorsque le processus a été lié au réseau WiFi et que vous souhaitez toujours utiliser le mobile. Au lieu de rechercher le WiFi (ce que j’essayais d’expérimenter au lieu de lier le processus), vous recherchez l’objet 'Réseau' pour mobile et vous lui créez une prise.
Nous avons besoin de quelque chose qui indique à Android de ne pas abandonner la connexion WiFi.
HttpUrlConnection ne vous permet pas d'obtenir le socket, vous pouvez donc utiliser okhttp pour le faire au niveau de chaque connexion. J'utilise 2.7.5 de OkHttp mais c'est très similaire pour la version 3+ de OkHttp.
Vous obtenez les réseaux actuels, puis traitez chacun pour trouver le réseau WiFi.
Network[] networks = connectivityManager.getAllNetworks();
Ensuite, vous construisez l'URL comme:
String url = "http://someurl";
HttpUrlConnection uconn = new OkUrlFactory( new OkHttpClient().setSocketFactory(network.getSocketFactory())).open(url)
Tout cela fonctionne bien pour quelques connexions et parfois cela fonctionne pour la série de connexions que j'ai utilisée. Android utilise la connaissance que l'activité se produit sur le réseau, mais qu'il y a des pauses et que l'utilisation du mobile est rétablie. Android 9 wifi est juste imparfait et n'a pas trouvé comment le rendre collant en utilisant la solution de socket. Il peut y en avoir un.
Je suis actuellement confronté au même problème pour le téléphone plus récent avec Android 8. +. J'utilise WifiManager, appelez bindProcessToNetwork
ici cela permettra au trafic de données de passer par le wifi sans accès à Internet,
voici comment je connecte mon téléphone au point d'accès
//Method to connect to WIFI Network
public boolean connectTo(String networkSSID, String key) {
WifiConfiguration config = new WifiConfiguration();
WifiInfo info = wifi.getConnectionInfo(); //get WifiInfo
int id = info.getNetworkId(); //get id of currently connected network
config.SSID = "\"" + networkSSID + "\"";
if (key.isEmpty()) {
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
}
int netID = wifi.addNetwork(config);
int tempConfigId = getExistingNetworkId(config.SSID);
if (tempConfigId != -1) {
netID = tempConfigId;
}
boolean disconnect = wifi.disconnect();
wifi.disableNetwork(id); //disable current network
boolean enabled = wifi.enableNetwork(netID, true);
boolean connected = wifi.reconnect();
if (((Build.VERSION.SDK_INT >= Build.VERSION_CODES.M))
|| ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop)
&& !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M))) {
final ConnectivityManager manager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder;
builder = new NetworkRequest.Builder();
//set the transport type do WIFI
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
manager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
manager.bindProcessToNetwork(network);
} else {
ConnectivityManager.setProcessDefaultNetwork(network);
}
try {
} catch (Exception e) {
e.printStackTrace();
}
manager.unregisterNetworkCallback(this);
}
});
}
une fois connecté au point d’accès créé par l’appareil, celui-ci en descendra constamment.
J'ai eu le même problème. Voici comment je résous ce problème dans les appareils Android 8+. 1. Depuis Android 8+, les appareils basculent automatiquement entre les appareils WiFI et cellulaires. J'ai enlevé le code ci-dessous. Code pour forcer le passage au wifi.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
NetworkRequest.Builder request = new NetworkRequest.Builder();
Log.i("forceCellularConnection","request WIFI enable");
request.addCapability(NetworkCapabilities.TRANSPORT_WIFI);
connectivityManager.requestNetwork(request.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManager.setProcessDefaultNetwork(network);
connectivityManager.bindProcessToNetwork(network);
}
}
});
}
Également ajouté ci-dessous le code pour oublier la connexion wifi avant de procéder à une nouvelle connexion. Il faut un certain temps à l’appareil pour déconnecter WiFI. J'ai donc ajouté un délai avant la connexion au nouveau SSID WIFI.
this.wifiManager.disableNetwork(configuration.networkId);
this.wifiManager.removeNetwork(configuration.networkId);
this.wifiManager.saveConfiguration(); // Not needed in API level 26 and above
Les solutions ci-dessous que j'ai essayées et qui m'ont aidé à établir la connexion sont les suivantes: Dans mon cas, je dois également me connecter au Wi-Fi qui ne dispose pas d'Internet. C'est une connexion peer to peer.
J'ai fait 2-3 tentatives de connexion
new CountDownTimer(16000, 2000) {
J'ai également écrit ci-dessous le récepteur de diffusion pour vérifier l'état du WiFI. Et puis fait la connexion.
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
Log.d("WifiReceiver", ">>>>SUPPLICANT_STATE_CHANGED_ACTION<<<<<<");
SupplicantState supl_state = ((SupplicantState) intent
.getParcelableExtra(WifiManager.EXTRA_NEW_STATE));
switch (supl_state) {
case ASSOCIATED:
Log.i("SupplicantState", "ASSOCIATED");
// authMsg = "ASSOCIATED";
break;
case ASSOCIATING:
// authMsg = "ASSOCIATING";
Log.i("SupplicantState", "ASSOCIATING");
break;
case AUTHENTICATING:
// authMsg = "AUTHENTICATING";
Log.i("SupplicantState", "Authenticating...");
break;
case COMPLETED:
authMsg = "CONNECTED";
Log.i("SupplicantState", "Connected");
final ConnectivityManager connection_manager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder request = new NetworkRequest.Builder();
request.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
connection_manager.registerNetworkCallback(request.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
ConnectivityManager.setProcessDefaultNetwork(network);
}
});
break;
case DISCONNECTED: