Hvernig á að athuga í kóða hvort VPN sé tengt á Android
Android hefur engan getter fyrir VPN-tengingu. Spurðu um netgetu, fylgstu með transportbreytingum og haltu samþykki appsins, stöðu tækisins og sönnun þjónsins aðskildum.
Þú getur ekki spurt Android hvort VPN sé tengt. VpnService afhjúpar engan getter fyrir tengingu, og lykilinn í stöðustikunni teiknar kerfið, ekki eitthvað sem appið þitt getur lesið. Það sem þú getur gert er að spyrja tengingarstakkinn þrengri spurningu: hvaða net notar umferð þessa apps, og ber það net VPN-transportinn. Þessi handbók fer í gegnum athuganirnar í þeirri röð sem kemur í veg fyrir falskar jákvæðar niðurstöður, frá shell-skipun á tækinu til callback sem þú lætur keyra í appinu.
Athugaðu tækið úr shell áður en þú snertir kóða appsins
Fáðu fyrst grunnlínu. adb shell dumpsys connectivity prentar hvert net sem kerfið þekkir, og hver blokk telur upp transportana sína, svo VPN-net birtist með VPN í þeim lista. Lestu blokk sjálfgefna netsins fyrir allt annað og leitaðu svo að öðrum netum sem bera sama transport.
Tvær útkomur svara mismunandi spurningum. Tilvist VPN-nets er ekki það sama og hvort appið þitt notar það, og á tæki með vinnusniði eða öðrum notanda geta bæði verið sannar á sama tíma á meðan ferlið þitt talar beint við internetið. Línan um virka netið er sú sem ræður því hvað socketin þín gera.
Biddu um netið sem appið notar
Í kóða er getuprófið fjórar línur. Biddu um ACCESS_NETWORK_STATE í manifestinu og berðu svo getu virka netsins saman við VPN-transportinn:
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);
Svarið er viljandi þröngt: er sjálfgefna net appsins VPN núna. Það segir ekkert um hvaða VPN það er, hvort það er þitt eða hvort göngin ná til fjarlæga endans. Meðhöndlaðu true sem „umferð fer út um einhver göng“ og haltu þínu eigin bókhaldi aðskildu. Boolean sem þýðir þrjá hluti í einu án þess að segja frá er ástæðan fyrir því að stillingaskjár endar á að tilkynna VPN sem slökkt á meðan notandinn vafrar í gegnum það.
Þegar þú þarft í staðinn að vita hvort eitthvert VPN-net sé til staðar, endurtaktu yfir cm.getAllNetworks() og prófaðu hvert getusett. Svörin tvö greinast á tæki sem keyrir VPN fyrir hvert app sem nær yfir önnur forrit en ekki þitt, og sú greining er uppspretta flestra villuskýrslna sem segja að appið sjái ekki VPN sem er augljóslega kveikt.
Fylgstu með breytingum í stað þess að spyrja reglulega
Regluleg fyrirspurn með tímamæli er rangt form fyrir þessa spurningu, því stöðubreytingar koma sem atburðir. Skráðu beiðni sem passar við VPN-transportinn og láttu rammann segja þér hvenær samsvarandi net birtist, hverfur eða breytist:
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
.build();
cm.registerNetworkCallback(request, callback);
VPN-net ber aldrei NET_CAPABILITY_NOT_VPN, svo hið skýrlega brotthvarf skjalfestir áætlunina. Án þess passar beiðnin samt, en næsta manneskja sem les kóðann verður að átta sig á því sjálf.
Skráningin tilheyrir því umfangi sem þarf athugunina, venjulega skjá eða forgrunnsþjónustu. Afskráðu í onStop eða onDestroy og skildu ekki callback eftir tengt við athöfn sem er þegar farin. App án sýnilegs hluta er slæmur gestgjafi fyrir varanlegan áhorfanda, og þau callback sem þú gleymir eru þau sem hrynja eftir stillingabreytingu.
Haltu þremur spurningum aðskildum
Mest ruglingsins á þessu sviði kemur af því að meðhöndla þrjár mismunandi athuganir sem eina. Þær nota mismunandi API, og hver um sig getur verið sönn á meðan hinar eru falskar.
| 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 |
Þriðja röðin er sú sem fólk reynir að svara hjá biðlaranum, og það er ekki hægt þar. Gefðu VPN-biðlurum sinn eigin vistfangasafn og lestu upprunavistfangið á þjóninum; það er eina sönnunin sem lifir af að notandi skipti um göng mitt í setu.
Sannprófunarröð sem útilokar falskar jákvæðar niðurstöður
Eldra dæmakóði sem er enn í umferð kallar á getNetworkInfo(ConnectivityManager.TYPE_VPN). Það kall er úrelt, og í nokkrum útgáfum skilaði það null jafnvel þótt VPN væri tengt, og þess vegna virðast svo mörg afrituð brot biluð á tæki sem virkar. Getuathuganir komast hjá gildrunni og haga sér eins frá Android 5.0. Ef þú viðheldur kóðagrunni sem kallar enn á það, skiptu kallinu út í stað þess að vefja því í varaleið, því varaleiðin var það sem framleiddi ranga svarið í fyrstu.
Ein flýtileið á skilið viðvörun. Að bera saman opinbera vistfangið sem utanaðkomandi þjónusta tilkynnir við útgangsvistfang VPN-sins sannar eitthvað um slóðina, en bætir beiðni til þriðja aðila við hverja athugun, fer eftir því að sú þjónusta haldist uppi og getur verið skyggð eða blokkuð. Haltu því sem handvirkri greiningu, aldrei sem stöðuathugun inni í appinu.
Keyrðu athuganirnar í þessari röð og staldraðu við þá fyrstu sem stangast á við skýrslu notandans: transportlisti í shell, geta virka netsins, callback-atburðir á meðan þú kveikir og slekkur á göngunum, svo upprunavistfang á þjónahlið. Ef allar fjórar stemma og appið hagar sér samt illa, er villan í þinni eigin stöðuvél en ekki í sýn Android á netinu.