Jinsi ya kukagua kwenye msimbo ikiwa VPN imeunganishwa kwenye Android
Android haina getter ya hali ya muunganisho wa VPN. Uliza uwezo wa mtandao, fuatilia mabadiliko ya usafirishaji, na tenga ridhaa ya programu, hali ya kifaa na uthibitisho wa seva.
Huwezi kumuuliza Android ikiwa VPN imeunganishwa. VpnService haitoi getter ya hali ya muunganisho, na aikoni ya ufunguo kwenye upau wa hali huchorwa na mfumo, si kitu ambacho programu yako inaweza kusoma. Unachoweza kufanya ni kuuliza steki ya muunganisho swali jembamba zaidi: mtandao upi unaotumiwa na trafiki ya programu hii, na mtandao huo unabeba usafirishaji wa VPN. Mwongozo huu unapitia ukaguzi kwa mpangilio unaoepuka matokeo chanya ya uongo, kuanzia amri ya shell kwenye kifaa hadi callback unayoiacha ikiendesha kwenye programu.
Kagua kifaa kutoka kwenye shell kabla ya kugusa msimbo wa programu
Kwanza pata hali ya msingi. adb shell dumpsys connectivity huchapisha kila mtandao ambao mfumo unaujua, na kila kizuizi huorodhesha usafirishaji wake, kwa hiyo mtandao wa VPN huonekana ukiwa na VPN kwenye orodha hiyo. Soma kizuizi cha mtandao chaguo-msingi kabla ya kitu kingine chochote, kisha tafuta mitandao mingine inayobeba usafirishaji huo huo.
Matokeo mawili hujibu maswali tofauti. Kuwepo kwa mtandao wa VPN si sawa na programu yako kuutumia, na kwenye kifaa kilicho na wasifu wa kazi au mtumiaji wa pili vyote viwili vinaweza kuwa kweli kwa wakati mmoja wakati mchakato wako unazungumza moja kwa moja na intaneti. Mstari wa mtandao amilifu ndio unaoamua soketi zako zinafanya nini.
Uliza mtandao ambao programu inautumia
Kwenye msimbo jaribio la uwezo ni mistari minne. Omba ACCESS_NETWORK_STATE kwenye manifest, kisha linganisha uwezo wa mtandao amilifu na usafirishaji wa VPN:
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);
Jibu ni jembamba kwa makusudi: mtandao chaguo-msingi wa programu ni VPN kwa sasa. Haisemi kitu kuhusu VPN ipi, ikiwa ni yako, au ikiwa handaki hufika upande wa pili. Chukulia true kama “trafiki hutoka kupitia handaki fulani” na weka hesabu zako tofauti. Boolean inayomaanisha mambo matatu kimyakimya kwa wakati mmoja ndiyo sababu skrini ya mipangilio huripoti VPN kama imezimwa wakati mtumiaji anavinjari kupitia hiyo.
Kinyume chake, unapohitaji kujua ikiwa mtandao wowote wa VPN upo, rudia cm.getAllNetworks() na jaribu kila seti ya uwezo. Majibu mawili hutofautiana kwenye kifaa kinachoendesha VPN maalum ya programu inayofunika programu nyingine lakini si yako, na tofauti hiyo ndiyo chanzo cha ripoti nyingi za hitilafu zinazosema programu haioni VPN iliyo wazi imewashwa.
Fuatilia mabadiliko badala ya kuchunguza mara kwa mara
Kuchunguza mara kwa mara kwa kipima muda ni umbo lisilofaa kwa swali hili, kwa sababu mabadiliko ya hali huja kama matukio. Sajili ombi linalolingana na usafirishaji wa VPN na uache mfumo ukueleze mtandao unaolingana unapotokea, kutoweka au kubadilika:
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
.build();
cm.registerNetworkCallback(request, callback);
Mtandao wa VPN haubebi NET_CAPABILITY_NOT_VPN kamwe, kwa hiyo kuondoa kwa uwazi kunaandika nia. Bila hiyo ombi bado linalingana, lakini mtu anayefuata kusoma msimbo lazima afikirie hilo mwenyewe.
Usajili ni wa wigo unaohitaji uchunguzi, kwa kawaida skrini au huduma ya mbele. Ondoa usajili kwenye onStop au onDestroy, na usiache callback ikining'inia kwenye shughuli ambayo tayari imeondoka. Programu isiyo na kipengele kinachoonekana ni mwenyeji mbaya kwa mchunguzi wa kudumu, na callback unazosahau ndizo zinazoanguka baada ya mabadiliko ya usanidi.
Tenga maswali matatu
Mkanganyiko mwingi katika eneo hili unatokana na kuchukua ukaguzi tatu tofauti kama mmoja. Hutumia API tofauti, na kila mmoja unaweza kuwa kweli wakati wengine ni uongo.
| 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 |
Mstari wa tatu ndio ambao watu hujaribu kuujibu kwenye mteja, na hauwezi kujibiwa hapo. Wape wateja wa VPN dimbwi lao la anwani na soma anwani ya chanzo kwenye seva; hiyo ndiyo uthibitisho pekee unaostahimili mtumiaji kubadilisha handaki katikati ya kipindi.
Mpangilio wa uthibitishaji unaoondoa matokeo chanya ya uongo
Msimbo wa mfano wa zamani ambao bado unazunguka huita getNetworkInfo(ConnectivityManager.TYPE_VPN). Wito huo umeacha kutumika na katika matoleo kadhaa ulirudisha null hata wakati VPN ilikuwa imeunganishwa, ndiyo sababu vipande vingi vilivyonakiliwa huonekana vimevunjika kwenye kifaa kinachofanya kazi. Ukaguzi wa uwezo huepuka mtego huo na hufanya kazi vivyo hivyo kuanzia Android 5.0. Ikiwa unasimamia msimbo ambao bado unaita, badilisha wito badala ya kuufunga kwenye fallback, kwa sababu fallback ndiyo iliyozalisha jibu lisilofaa mwanzoni.
Njia moja ya mkato inastahili tahadhari. Kulinganisha anwani ya umma inayoripotiwa na huduma ya nje na anwani ya kutoka ya VPN kunathibitisha kitu kuhusu njia, lakini kuongeza ombi la mtu wa tatu kwenye kila ukaguzi, hutegemea huduma hiyo kubaki hai, na inaweza kuhifadhiwa au kuzuiwa. Iweke kama uchunguzi wa mkono, kamwe usiwe ukaguzi wa hali ndani ya programu.
Endesha ukaguzi kwa mpangilio huu na usimame kwenye ule wa kwanza ambao haukubaliani na ripoti ya mtumiaji: orodha ya usafirishaji kutoka shell, uwezo wa mtandao amilifu, matukio ya callback unapowasha na kuzima handaki, kisha anwani ya chanzo upande wa seva. Ikiwa yote manne yanakubaliana na programu bado inafanya vibaya, hitilafu iko kwenye mashine yako ya hali, si kwenye mtazamo wa Android wa mtandao.