Forcer Android à utiliser le réseau Wifi sans internet

je construis une application android qui a besoin de communiquer sur un réseau WiFi qui n'aura pas d'accès internet. Le problème est que même lorsque le WiFi est connecté android choisit d'utiliser des données cellulaires/mobiles quand aucune connexion internet est présent sur le réseau wifi.

j'ai lu beaucoup de billets sur la question dont beaucoup impliquent d'enraciner l'appareil mais ce n'est pas possible avec une application de production (les dispositifs d'enracinement est une option). autre solution (comme mon code ci-dessous) suggérez d'utiliser bindProcessToNetwork() qui fonctionne parfaitement sur mon Sony Z2 mais pas sur les autres appareils que j'ai testés sur (tous fonctionnant avec 6.0.1)

private void bindToNetwork() {
    final ConnectivityManager connectivityManager = (ConnectivityManager) mActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkRequest.Builder builder;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        builder = new NetworkRequest.Builder();
        //set the transport type do WIFI
        builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
        connectivityManager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(Network network) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {


                    connectivityManager.bindProcessToNetwork(null);
                    if (barCodeData.getSsid().contains("screenspace")) {
                        connectivityManager.bindProcessToNetwork(network);
                    }

                } else {
                    //This method was deprecated in API level 23
                    ConnectivityManager.setProcessDefaultNetwork(null);
                    if (barCodeData.getSsid().contains("screenspace")) {

                        ConnectivityManager.setProcessDefaultNetwork(network);
                    }
                }

                connectivityManager.unregisterNetworkCallback(this);
            }
        });
    }
}
22
demandé sur Lonergan6275 2017-02-27 20:31:27

4 réponses

pouvez-vous essayer de définir le paramètre global captive_portal_detection_enabled à 0 (false).

ce qui se passe en fait, c'est que par défaut, chaque fois que vous vous connectez à un wifi, la FW teste contre un serveur (typiquement google) pour voir si c'est un wifi captif (nécessite une connexion). Donc, si votre réseau n'est pas connecté à google, cette vérification échoue. Après cela, l'appareil sait que wifi n'a pas de connexion internet et ne sera tout simplement pas autoconnect à elle.

la définition de cette le réglage à 0, évitera cette vérification.

par programme: Settings.Global.putInt(getContentResolver(), Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 0);

Edit: vous pouvez avoir besoin d'utiliser la chaîne de caractères "captive_portal_detection_enabled" directement, au lieu de la constante qui n'est pas visible selon la version Android.

1
répondu lax1089 2017-03-03 22:19:10

Vous pouvez vérifier si le wifi est connecté puis procéder autrement afficher un dialogue à l'utilisateur lui demandant de se connecter à un réseau wifi

depuis la méthode NetworkInfo.isConnected () est maintenant déprécié dans API-23, Voici une méthode qui détecte si L'adaptateur Wi-Fi est activé et aussi connecté à un point d'accès en utilisant WiFiManager à la place:

private boolean checkWifiOnAndConnected() {
    WifiManager wifiMgr = (WifiManager) getSystemService(Context.WIFI_SERVICE);

    if (wifiMgr.isWifiEnabled()) { // Wi-Fi adapter is ON

        WifiInfo wifiInfo = wifiMgr.getConnectionInfo();

        if( wifiInfo.getNetworkId() == -1 ){
            return false; // Not connected to an access point
        }
        return true; // Connected to an access point
    }
    else {
        return false; // Wi-Fi adapter is OFF
    }
}
1
répondu Akshay Sood 2017-06-20 07:50:45

vous devez désactiver les données mobiles dans les paramètres (pas certain, si cela peut être fait par programmation, ce qui pourrait être une option possible) - ou sortir L'USIM;

sinon le comportement commun est, qu'il retombera toujours à la meilleure connexion disponible (alors qu'une connexion avec passerelle internet pourrait être préférable, parce qu'il est utilisé par la plupart des applications).

voir aussi réponse.

0
répondu Martin Zeitler 2017-04-13 12:18:19

vous êtes dans la bonne voie, la solution est en effet avec ConnectivityManager.bindProcessToNetwork (network). Cette information a été postée sur le blog des Développeurs Android dans cet article:Connexion de votre Application à un Appareil Wi-Fi.

regarder dans votre code ceci barCodeData.getSsid() n'a pas l'air de recevoir le SSID du réseau wifi actuellement connecté. Si c'est le cas, votre code ne se liera jamais avec succès au réseau.

essayer de remplacer votre si la déclaration

if (barCodeData.getSsid().contains("screenspace"))

if (getNetworkSsid(context).equals("screenspace"))

méthode de L'aide dans kotlin pour récupérer le SSID du réseau wifi connecté

private fun getNetworkSsid(context: Context?): String {
    // WiFiManager must use application context (not activity context) otherwise a memory leak can occur
    val mWifiManager = context?.applicationContext?.getSystemService(Context.WIFI_SERVICE) as WifiManager
    val wifiInfo: WifiInfo? = mWifiManager.connectionInfo
    if (wifiInfo?.supplicantState == SupplicantState.COMPLETED) {
        return wifiInfo.ssid.removeSurrounding("\"")
    }
    return ""
}

Si ne fonctionne toujours pas, veuillez suivre ma solution complète où j'ai utilisé la même méthode, mais avec quelques contrôles supplémentaires. Je l'ai testé dans les versions d'Android 5.1.1, 6.0, 6.0.1, 7.1.1 et 8.1.0.

0
répondu Ryan Amaral 2018-07-22 23:24:55