Wéi een am Code iwwerpréift, ob eng VPN op Android verbonnen ass
Android huet kee Getter fir de VPN-Verbindungsstatus. Frot d'Netzwierkfäegkeeten of, iwwerwaach Transportännerungen an haalt App-Zoustëmmung, Apparat-Zoustand a Server-Beweis getrennt.
Dir kënnt Android net froen, ob eng VPN verbonnen ass. VpnService bitt kee Getter fir de Verbindungsstatus un, an d'Schlëssel-Ikon an der Statusleesch gëtt vum System gezeechent, net vun eppes, wat Är App liese kann. Wat Dir maache kënnt, ass dem Konnektivitéits-Stack eng méi enk Fro ze stellen: wéi ee Netzwierk de Traffic vun dëser App benotzt, a wéi ob dëst Netzwierk den VPN-Transport dréit. Dësen Runbook geet d'Kontrollen an der Rei duerch, déi falsch Positiver vermeit, vun engem Shell-Kommando um Apparat bis bei de Callback, deen Dir an der App lafe loosst.
Kontrolléiert den Apparat vun enger Shell, ier Dir den App-Code beréiert
Huelt d'éischt eng Basis. adb shell dumpsys connectivity dréckt all Netzwierk, dat de System kennt, an all Block lëscht seng Transporten op, sou datt en VPN-Netzwierk mat VPN an där Lëscht erschéngt. Liest den Default-Netzwierkblock virun allem aneren, a sicht duerno aner Netzwierker, déi deen selwechten Transport droen.
Zwee Ausgaben äntwerten op verschidde Froen. Ob en VPN-Netzwierk existéiert ass net datselwecht wéi ob Är App et benotzt, an op engem Apparat mat engem Aarbechtsprofil oder engem zweete Benotzer kënnen zwou Saachen gläichzäiteg wouer sinn, während Äre Prozess direkt mam Internet schwätzt. D'Linn vum aktiven Netzwierk ass déi, déi entscheet, wat Är Sockets maachen.
Frot no dem Netzwierk, dat d'App benotzt
Am Code ass den Test vun de Fäegkeeten véier Zeilen. Frot ACCESS_NETWORK_STATE am Manifest un, a vergläicht dann d'Fäegkeete vum aktiven Netzwierk mam VPN-Transport:
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
Network active = cm.getActiveNetwork();
NetworkCapabilities caps = cm.getNetworkCapabilities(active);
boolean vpnInUse = caps != null
&& caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
D'Äntwert ass bewosst enk: ass den Default-Netzwierk vun der App just elo eng VPN. Si seet näischt doriwwer, wéi eng VPN, ob si Är ass, oder ob den Tunnel säin aneren Enn erreecht. Betruecht en true als “den Traffic geet duerch en Tunnel eraus” a haalt Är eege Buchféierung getrennt. E Boolean, deen onbemierkt dräi Saachen gläichzäiteg bedeit, ass de Grond, firwat en Astellungsbildschierm d'VPN als aus ugëtt, während de Benotzer duerch si browst.
Wann Dir dogéint wësse musst, ob iwwerhaapt en VPN-Netzwierk präsent ass, iteréiert iwwer cm.getAllNetworks() a test all Fäegkeetsset. Déi zwou Äntwerten divergéieren op engem Apparat mat enger App-spezifescher VPN, déi aner Applikatiounen deckt, Är awer net, an déi Divergenz ass d'Quell vun de meeschte Bugreporten, déi soen, d'App gesinn eng VPN net, déi kloer un ass.
Iwwerwaacht Ännerungen amplaz ze polléieren
Polling mat engem Timer ass déi falsch Form fir dës Fro, well Zoustandsännerungen als Eventer ukommen. Registréiert eng Ufro, déi mam VPN-Transport iwwerenee kënnt, a loosst de Framework Iech soen, wéini en entspriechend Netzwierk erschéngt, verschwënnt oder sech ännert:
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
.build();
cm.registerNetworkCallback(request, callback);
En VPN-Netzwierk dréit ni NET_CAPABILITY_NOT_VPN, dofir dokumentéiert déi explizit Ewechhuelen d'Absicht. Ouni si passt d'Ufro nach ëmmer, awer déi nächst Persoun, déi de Code liest, muss dat selwer erausfannen.
D'Registrierung gehéiert zu deem Geltungsberäich, deen d'Observatioun brauch, meeschtens en Bildschierm oder en Foreground-Service. Mell of an onStop oder onDestroy, a loosst kee Callback op enger Activity hänken, déi schonn ewech ass. Eng App ouni sichtbar Komponent ass en schlechten Host fir en permanente Observateur, an déi Callbacken, déi Dir vergiess, sinn déi, déi no enger Konfiguratiounsännerung crashen.
Haalt dräi Froen auserneen
De meeschte Verwirrung an dësem Beräich kënnt dohier, dräi verschidde Kontrollen als eng ze behandelen. Si benotze verschidden APIs, an alleng ka wouer sinn, während déi aner falsch sinn.
| Question | How you answer it | What a yes means |
|---|---|---|
| Did the user grant VPN consent to my app? | VpnService.prepare() returns null | Consent exists; the tunnel may still be down |
| Is the device sending default traffic through a VPN? | TRANSPORT_VPN on the active network | Something is tunneling, not necessarily your app |
| Did this request arrive through the VPN? | Source address seen by the server | Proof for that connection, nothing wider |
Déi drëtt Rei ass déi, déi d'Leit um Client probéieren ze beäntwerten, an do kann een se net beäntwerten. Gitt VPN-Clients hire eigenen Adresspool a liest d'Quelladress um Server; dat ass deen eenzegen Beweis, deen e Benotzer iwwerlieft, deen mëttlerweil den Tunnel wiesselt.
Iwwerpréifungsuerdnung, déi falsch Positiver ausschléisst
Méi alen Beispillcode, deen nach ëmmer am Ëmlaf ass, rufft getNetworkInfo(ConnectivityManager.TYPE_VPN) op. Dee Opruff ass deprecated, an op verschiddene Releases huet en null zréckginn, och während eng VPN verbonnen war, dofir gesinn sou vill kopéiert Schnësselen op engem Apparat futti aus, dee funktionéiert. Fäegkeetskontrollen ëmgoen déi Falle a verhalen sech zënter Android 5.0 gläich. Wann Dir eng Codebase ënnerhalet, déi en nach ëmmer oprufft, ersetzt den Opruff, amplaz en an e Fallback ze wéckelen, well de Fallback dat war, wat déi falsch Äntwert produzéiert huet.
Eng Ofkierzung verdéngt eng Warnung. D'ëffentlech Adress, déi en externen Service mellt, mat der VPN-Exitadress ze vergläichen, beweist eppes iwwer de Wee, mee et bäisetzt all Kontroll eng Ufro vun Drëtten, hänkt dovun of, datt dee Service weiderleeft, a ka gecacht oder blockéiert ginn. Haalt se als manuell Diagnostik, ni als Zoustandskontroll an der App.
Féiert d'Kontrollen an dëser Rei aus a stoppt bei der éischter, déi dem Benotzer sengem Rapport widersprécht: Shell-Transportlëscht, Fäegkeete vum aktiven Netzwierk, Callback-Evenementer wärend Dir den Tunnel un- an ausschalt, dann d'Quelladress op der Serversäit. Wann all véier iwwerenee stëmmen an d'App sech nach ëmmer falsch verhält, ass de Bug an Ärer eegener Zoustandsmaschinn, net an Android senger Vue vum Netzwierk.