2
votes

Android 9 - Socket Connect TIMEOUT lorsque les données mobiles sont activées

J'ai une application déployée qui échoue sur Android 9. Une partie de sa fonction est de configurer un module sur un réseau de points d'accès pour permettre à ce module de se connecter au réseau domestique des utilisateurs.

J'ai du code qui détecte et se connecte au bon réseau WIFI, mais lorsque j'essaie d'ouvrir une prise sur l'appareil, cela échoue - uniquement sur Android 9 et uniquement si les données mobiles sont activées. Si je désactive manuellement les données mobiles sur l'appareil, tout fonctionne correctement.

Socket open() {
    Socket sock = new Socket(Proxy.NO_PROXY);
    try {
        sock.bind(new InetSocketAddress(localIpAddress(), 50000));
    } catch (IOException e) {
        activity.logContent("Warning: Failed to bind socket : " + e.toString());
    }
    try {
        sock.connect(new InetSocketAddress("192.168.17.1", 5555), (int)5000);
    } catch (IOException e) {
        // This catch fires when Mobile Data is on.
        activity.logContent("Connected to " + activity.mWifiManager.getConnectionInfo().getSSID());
        activity.logContent("Couldn't open socket : " + e.toString());
    }
    return sock;
}

J'ai essayé cela avec et sans le Proxy.NO_PROXY et avec et sans l'appel bind () . Si l'appel de liaison est manquant, l'erreur implique que le socket tente de se connecter via le réseau cellulaire. (Remarque: activity.logContent () est un journal à l'écran, il est donc plus facile de voir ce qui se passe lorsqu'il n'est pas connecté à un débogueur.

Toutes les idées de ce qui se passe faux?


1 commentaires

veuillez vous référer à ce lien stackoverflow.com/questions/35152417/... je rencontre le même problème


3 Réponses :


1
votes

Dans Android 9, il existe une configuration de sécurité sur le réseau: Configuration de sécurité Android

L'ajout de votre domaine dans network_security_config peut résoudre votre problème. J'avais ceci dans mon network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">119.xxx.xxx.xxx</domain>
    </domain-config>
</network-security-config>


1 commentaires

Merci pour cette suggestion, j'ai déjà ce fichier, mais le projet est construit contre 19, donc je ne suis pas sûr que le fichier d'autorisations soit utilisé. De plus, je (crois?) Que vous obtenez une erreur différente dans ce cas (pas un délai d'expiration, mais une erreur de sécurité), et cela n'explique pas pourquoi le code fonctionne lorsque les données mobiles sont désactivées (forçant ainsi la prise à se connecter via Wifi ?)



1
votes

Je ne suis pas sûr de la raison exacte pour laquelle cela se produit. Cependant, lorsque vous allumez vos données mobiles et que vous êtes uniquement connecté à Internet en utilisant vos données mobiles (en considérant que votre wifi est désactivé), il obtient l'adresse IP du réseau cellulaire qui n'est plus connecté à votre réseau domestique. Par conséquent, il est trivial de s'attendre à de tels scénarios de délai d'attente, car il ne peut pas atteindre les adresses IP privées de votre réseau domestique commençant par 192.168 .... .

Maintenant, ma confusion est que même si les données mobiles sont activées et que le Wi-Fi et les données mobiles sont activés en même temps, l'appareil doit se connecter au Wi-Fi par défaut.

Par conséquent, je voudrais vous suggérer de vérifier ce qui suit.

  • Android 9 (Pie) présente une Préférence Wifi , qui empêche la connexion automatique aux réseaux publics. Vous pourriez envisager de vérifier les paramètres.
  • Veuillez vérifier l'adresse IP de votre appareil et vérifier s'il possède une adresse IP commençant par 192.168 .... . Sinon, alors certainement, vous obtenez votre adresse IP de votre réseau cellulaire et ne peut donc pas atteindre vos adresses IP privées du réseau domestique.

1 commentaires

Merci d'avoir indiqué la préférence WiFi. L'appareil que nous avons inclut également la possibilité de nous définir des applications spécifiques ou de ne pas utiliser les données mobiles. La modification de ces préférences n'a aucun impact. L'appel localIpAddress () sur l'appareil se résout en 192.168.17.2 qui est l'adresse IP du point d'accès de l'appareil.



1
votes

Après quelques jours d'imprécations je crois être arrivé à l'identification du problème et donc à la solution:

Le problème survient en raison de quelques changements dans la version d'Android (je présume être 9.0 même si d'autres modifications avaient eu lieu sur l'API 21), en particulier lors de la création de la socket, si le système détecte qu'il y a un "meilleur" réseau (accès à internet, signal élevé, etc, etc) la création de socket se réfère à ce réseau et non plus au réseau wifi que vous souhaitez.

J'ai cherché des moyens de forcer la création de la prise sur le réseau wifi (qui est le réseau que je veux) et le seul moyen que j'ai trouvé est le suivant: p >

Simplement mis à la place de:

Socket sock = new Socket ();

Faites:

ConnectivityManager connectivity = (ConnectivityManager) MyApp.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
                if (connectivity != null)
                {
                    for (Network network : connectivity.getAllNetworks())
                    {
                        NetworkInfo networkInfo = connectivity.getNetworkInfo(network);

                        if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI)
                        {
                            if (networkInfo.isConnected())
                            {
                                Socket sock =  network.getSocketFactory().createSocket();
                            }
                        }
                    }
            }

Parcourez pratiquement les réseaux présents dans l'appareil et lorsque vous trouvez votre wifi actif vous ne faites rien d'autre que profiter de cette fonction pour obtenir la bonne prise à coup sûr:

getSocketFactory (). createSocket () strong >

Vous avez maintenant le socket de travail !

Dans mon cas cela fonctionne maintenant parfaitement, si quelqu'un trouve de meilleures solutions, c'est bienvenu, mais pour l'instant c'est le seul moyen que j'ai trouvé pour que tout fonctionne comme dans la version précédente d'Android.


1 commentaires

Mon client a confirmé que cela a résolu ses problèmes. Merci.