Il y a 8 ans -
Temps de lecture 3 minutes
Injecter l’IP host avec Gradle
Lorsqu’on développe une application Android, il nous arrive souvent, si ce n’est toujours, d’avoir à réaliser des appels réseaux. Nous avons donc régulièrement besoin de lancer nous-même la partie serveur sur nos PC afin de réaliser nos développements ou des tests.
Cependant, notre adresse IP, et donc cette configuration, est unique à chaque développeur et les contraint à modifier leur build.gradle. Ce changement présente un risque puisque ces modifications peuvent être poussées sur le serveur de gestion de source et poser problème à l’environnement des autres développeurs. Dans cette situation, comment arriver à faire en sorte que notre application Android connaisse directement notre serveur et donc notre adresse IP locale ?
Encore mieux : est-il possible de gérer cela directement au niveau du build ? C’est ce que nous allons voir dans ce court article.
Et si on regardait dans la doc ?
Premier (bon) réflexe, regarder dans le JDK. On y trouve la méthode InetAddress.getLocalHost(), qui permet de récupérer l’adresse IP locale de l’host. Cependant, en continuant les recherches, on se rend rapidement compte que cette méthode présente quelques ambiguités sur les systèmes UNIX et que bien souvent 127.0.0.1 est retourné.
Et si on demandait à Google ?
Si on réalise une recherche Google rapide sur ce sujet, on tombe sur un de Dominic Bartl. Sa solution consiste à donner, au moment du build, l’interface réseau connectée du PC afin de récupérer l’adresse IP en veillant à ce qu’elle soit bien au format IPV6. Son code est le suivant :
[groovy]// Get the ip address by interface name
def getLocalIp(String interfaceName) {
NetworkInterface iface = NetworkInterface.getByName(interfaceName);
for (InterfaceAddress address : iface.getInterfaceAddresses()) {
String ip = address.getAddress().getHostAddress()
if (ip.length() <= 15) {
return ip;
}
}
}[/groovy]
Ce code est une très bonne première étape mais il présente plusieurs problèmes :
- l’interface réseau peut varier d’un PC à l’autre,
- l’interface réseau varie selon le type de connexion (Ethernet, WIFI, …).
Comment fait on alors ?
La solution que nous avons mise en place réside dans le code suivant :
[groovy]def getIP() {
InetAddress result = null;
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
Enumeration<InetAddress> addresses = networkInterfaces.nextElement().getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress address = addresses.nextElement();
if (!address.isLoopbackAddress()) {
if (address.isSiteLocalAddress()) {
return address.getHostAddress();
} else if (result == null) {
result = address;
}
}
}
}
return (result != null ? result : InetAddress.getLocalHost()).getHostAddress();
}[/groovy]
Elle s’inspire fortement de celle présentée dans un premier temps. Nous passons en revue l’ensemble des interfaces réseaux et l’ensemble de leurs adresses IP jusqu’à trouver une adresse IP non loopback et site local. Si aucune adresse n’est trouvée, nous retournons la première adresse non loopback rencontrée. Enfin, en dernier recours, nous utilisons la méthode InetAddress.getLocalHost() du JDK.
Cette solution a été éprouvée sur différents environnements et également sur le simulateur Genymotion.
Comment on l’utilise ?
Afin de profiter pleinement des avantages de Gradle et de ses bonnes pratiques, nous allons déclarer notre adresse IP (et donc notre URL serveur) directement dans le BuildConfig généré de la façon suivante :
[groovy]buildTypes {
debug {
buildConfigField ‘String’, ‘URL_SERVER’, "\"http://${getIP()}\""
}
release {
buildConfigField ‘String’, ‘URL_SERVER’, "\"http://www.prod.com\""
}
}[/groovy]
Vous avez donc maintenant une façon simple et rapide pour pouvoir récupérer et donner à votre application Android, l’adresse IP de votre serveur local. En espérant que cela vous sera utile.
Commentaire