Nuk mund t'i pyesni Android nëse një VPN është i lidhur. VpnService nuk ekspozon asnjë getter për gjendjen e lidhjes, dhe ikona e çelësit në shiritin e statusit vizatohet nga sistemi, jo nga diçka që aplikacioni juaj mund të lexojë. Ajo që mund të bëni është t'i bëni stivës së lidhshmërisë një pyetje më të ngushtë: cilin rrjet po përdor trafiku i këtij aplikacioni dhe a e transporton ai rrjet transportin VPN. Ky udhëzues i kalon kontrollet sipas rendit që shmang pozitivat e rremë, nga një komandë shell në pajisje deri te callback-u që e lini të ekzekutohet në aplikacion.

Kontrolloni pajisjen nga një shell përpara se të prekni kodin e aplikacionit

Fillimisht merrni një bazë. adb shell dumpsys connectivity shtyp çdo rrjet që njeh sistemi, dhe çdo bllok liston transportet e veta, kështu që një rrjet VPN shfaqet me VPN në atë listë. Lexoni bllokun e rrjetit të parazgjedhur para çdo gjëje tjetër, pastaj kërkoni rrjetet e tjera që mbartin të njëjtin transport.

Dy dalje i përgjigjen pyetjeve të ndryshme. Ekzistenca e një rrjeti VPN nuk është e njëjtë me atë nëse aplikacioni juaj po e përdor atë, dhe në një pajisje me profil pune ose përdorues të dytë të dyja mund të jenë të vërteta njëkohësisht ndërsa procesi juaj flet drejtpërdrejt me internetin. Rreshti i rrjetit aktiv është ai që vendos se çfarë bëjnë socket-et tuaja.

Pyetni për rrjetin që përdor aplikacioni

Në kod testi i aftësive është katër rreshta. Kërkoni ACCESS_NETWORK_STATE në manifest, pastaj krahasoni aftësitë e rrjetit aktiv me transportin 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);

Përgjigja është qëllimisht e ngushtë: a është rrjeti i parazgjedhur i aplikacionit një VPN tani. Nuk thotë asgjë për cilin VPN, nëse është i juaji, apo nëse tuneli arrin skajin tjetër. Trajtojeni një true si “trafiku del përmes një tuneli” dhe mbani kontabilitetin tuaj veç. Një boolean që në heshtje nënkupton tri gjëra njëkohësisht është arsyeja pse një ekran cilësimesh raporton VPN-në si të fikur ndërsa përdoruesi shfleton përmes saj.

Kur përkundrazi ju duhet të dini nëse ka ndonjë rrjet VPN, përsëritni mbi cm.getAllNetworks() dhe testoni çdo grup aftësish. Dy përgjigjet ndryshojnë në një pajisje që ekzekuton një VPN për aplikacion që mbulon aplikacione të tjera por jo tuajin, dhe ai ndryshim është burimi i shumicës së raporteve të defekteve që thonë se aplikacioni nuk sheh një VPN qartësisht të ndezur.

Ndiqni ndryshimet në vend që të bëni polling

Polling-u me kohëmatës është forma e gabuar për këtë pyetje, sepse ndryshimet e gjendjes vijnë si ngjarje. Regjistroni një kërkesë që përputhet me transportin VPN dhe lërini kornizën t'ju thotë kur një rrjet përputhës shfaqet, zhduket ose ndryshon:

NetworkRequest request = new NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
    .build();
cm.registerNetworkCallback(request, callback);

Një rrjet VPN nuk e mbart kurrë NET_CAPABILITY_NOT_VPN, prandaj heqja e qartë dokumenton qëllimin. Pa të kërkesa përputhet gjithsesi, por personi tjetër që lexon kodin duhet ta kuptojë vetë.

Regjistrimi i përket fushës që ka nevojë për vëzhgimin, zakonisht një ekran ose një shërbim në plan të parë. Çregjistroni në onStop ose onDestroy, dhe mos lini një callback të varur në një aktivitet që ka ikur tashmë. Një aplikacion pa komponentë të dukshme është një pritës i dobët për një vëzhgues të përhershëm, dhe callback-ët që harroni janë ata që dështojnë pas një ndryshimi konfigurimi.

Mbani tri pyetje veç

Shumica e konfuzionit në këtë fushë vjen nga trajtimi i tri kontrolleve të ndryshme si një. Ato përdorin API të ndryshme, dhe secila mund të jetë e vërtetë ndërsa të tjerat janë të rreme.

QuestionHow you answer itWhat a yes means
Did the user grant VPN consent to my app?VpnService.prepare() returns nullConsent exists; the tunnel may still be down
Is the device sending default traffic through a VPN?TRANSPORT_VPN on the active networkSomething is tunneling, not necessarily your app
Did this request arrive through the VPN?Source address seen by the serverProof for that connection, nothing wider

Rreshti i tretë është ai që njerëzit përpiqen t'i përgjigjen në klient, dhe atje nuk mund t'i përgjigjen. Jepini klientëve VPN grupin e tyre të adresave dhe lexoni adresën burimore në server; kjo është e vetmja provë që i mbijeton një përdoruesi që ndryshon tunel në mes të sesionit.

Rendi i verifikimit që përjashton pozitivat e rremë

Kodi shembull më i vjetër që qarkullon ende thërret getNetworkInfo(ConnectivityManager.TYPE_VPN). Ai thirrje është e vjetruar dhe në disa versione kthente null edhe kur një VPN ishte i lidhur, prandaj kaq shumë copëza të kopjuara duken të prishura në një pajisje që funksionon. Kontrollet e aftësive e shmangin atë kurth dhe sillen njësoj që nga Android 5.0. Nëse mirëmbani një kod bazë që ende e thërret, zëvendësoni thirrjen në vend që ta mbështillni në një fallback, sepse fallback-u është ai që prodhoi përgjigjen e gabuar në radhë të parë.

Një shkurtojë meriton një paralajmërim. Krahasimi i adresës publike që raporton një shërbim i jashtëm me adresën e daljes së VPN-së provon diçka për rrugën, por shton një kërkesë të palës së tretë në çdo kontroll, varet nga qëndrimi i atij shërbimi dhe mund të ruhet në cache ose të bllokohet. Mbani si diagnostikim manual, kurrë si kontrolli i gjendjes brenda aplikacionit.

Ekzekutoni kontrollet në këtë rend dhe ndaloni në të parën që nuk përputhet me raportin e përdoruesit: lista e transporteve nga shell, aftësitë e rrjetit aktiv, ngjarjet e callback-ut ndërsa ndizni dhe fikni tunelin, pastaj adresa burimore në anën e serverit. Nëse të katër përputhen dhe aplikacioni vazhdon të sillet gabimisht, defekti është në makinën tuaj të gjendjes, jo në pamjen e Android për rrjetin.

Artikuj të ngjashëm