Android પર કોડમાં કેવી રીતે તપાસવું કે VPN કનેક્ટ છે
Android પાસે VPN કનેક્શન માટે કોઈ getter નથી. નેટવર્ક ક્ષમતાઓ પૂછો, ટ્રાન્સપોર્ટ ફેરફારો નિહાળો, અને એપની સંમતિ, ડિવાઇસની સ્થિતિ અને સર્વરનો પુરાવો અલગ રાખો.
તમે Android ને પૂછી શકતા નથી કે VPN કનેક્ટ છે કે નહીં. VpnService કોઈ કનેક્શન getter આપતું નથી, અને સ્ટેટસ બારમાંનું ચાવીનું ચિહ્ન સિસ્ટમ દોરે છે, એવું કંઈ નહીં જે તમારી એપ વાંચી શકે. તમે જે કરી શકો તે એ છે કે કનેક્ટિવિટી સ્ટેકને વધુ સાંકડો પ્રશ્ન પૂછો: આ એપનો ટ્રાફિક કયું નેટવર્ક વાપરે છે, અને એ નેટવર્ક VPN ટ્રાન્સપોર્ટ ધરાવે છે કે નહીં. આ માર્ગદર્શિકા ખોટા પોઝિટિવ ટાળતા ક્રમમાં તપાસ પસાર કરે છે, ડિવાઇસ પરની shell કમાન્ડથી લઈને એપમાં ચાલુ રાખેલા callback સુધી.
એપનો કોડ સ્પર્શ કરતા પહેલા shell થી ડિવાઇસ તપાસો
પહેલા આધારરેખા મેળવો. adb shell dumpsys connectivity સિસ્ટમને જાણીતા દરેક નેટવર્કને છાપે છે, અને દરેક બ્લોક તેના ટ્રાન્સપોર્ટની યાદી આપે છે, તેથી VPN નેટવર્ક એ યાદીમાં VPN સાથે દેખાય છે. બીજું કંઈ પણ પહેલા ડિફોલ્ટ નેટવર્કનો બ્લોક વાંચો, પછી એ જ ટ્રાન્સપોર્ટ ધરાવતાં બીજાં નેટવર્ક શોધો.
બે આઉટપુટ બે અલગ પ્રશ્નોના જવાબ આપે છે. VPN નેટવર્કનું અસ્તિત્વ એ તમારી એપ તેનો ઉપયોગ કરે છે કે નહીં તેની સમાન વાત નથી, અને વર્ક પ્રોફાઇલ કે બીજા વપરાશકર્તા ધરાવતા ડિવાઇસ પર બંને એકસાથે સાચા હોઈ શકે જ્યારે તમારી પ્રક્રિયા સીધી ઇન્ટરનેટ સાથે વાત કરે છે. સક્રિય નેટવર્કની લાઇન એ છે જે નક્કી કરે છે કે તમારા સોકેટ શું કરે.
એપ જે નેટવર્ક વાપરે છે તે માટે પૂછો
કોડમાં ક્ષમતા પરીક્ષણ ચાર લાઇન છે. મેનિફેસ્ટમાં ACCESS_NETWORK_STATE માંગો, પછી સક્રિય નેટવર્કની ક્ષમતાઓની 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);
જવાબ જાણી જોઈને સાંકડો છે: શું એપનું ડિફોલ્ટ નેટવર્ક અત્યારે VPN છે. તે કયું VPN છે, તમારું છે કે નહીં, કે ટનલ તેના દૂરના છેડે પહોંચે છે કે નહીં તે વિશે કંઈ કહેતું નથી. true ને “ટ્રાફિક કોઈ ટનલમાંથી નીકળે છે” તરીકે ગણો અને તમારું પોતાનું હિસાબ અલગ રાખો. જે બુલિયન ચૂપચાપ એકસાથે ત્રણ વસ્તુઓનો અર્થ રાખે છે તે જ કારણ છે કે સેટિંગ્સ સ્ક્રીન VPN ને બંધ બતાવે છે જ્યારે વપરાશકર્તા તેમાંથી બ્રાઉઝ કરી રહ્યો હોય.
જ્યારે તેના બદલે તમારે જાણવું હોય કે કોઈ પણ VPN નેટવર્ક હાજર છે કે નહીં, તો cm.getAllNetworks() પર પુનરાવર્તન કરો અને દરેક ક્ષમતા સેટ ચકાસો. બંને જવાબો એ ડિવાઇસ પર અલગ પડે છે જે પ્રતિ-એપ VPN ચલાવે છે જે બીજી એપ્લિકેશનોને આવરી લે છે પણ તમારીને નહીં, અને એ ભેદ જ મોટાભાગના બગ રિપોર્ટનો સ્રોત છે જે કહે છે કે એપ સ્પષ્ટપણે ચાલુ VPN જોઈ શકતી નથી.
પોલિંગને બદલે ફેરફારો નિહાળો
ટાઇમર પર પોલિંગ આ પ્રશ્ન માટે ખોટું સ્વરૂપ છે, કારણ કે સ્થિતિના ફેરફારો ઘટના તરીકે આવે છે. VPN ટ્રાન્સપોર્ટ સાથે મેળ ખાતી વિનંતી નોંધાવો અને ફ્રેમવર્કને કહેવા દો કે ક્યારે મેળ ખાતું નેટવર્ક દેખાય, અદૃશ્ય થાય કે બદલાય:
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
.build();
cm.registerNetworkCallback(request, callback);
VPN નેટવર્ક ક્યારેય NET_CAPABILITY_NOT_VPN ધરાવતું નથી, તેથી સ્પષ્ટ દૂર કરવું હેતુનું દસ્તાવેજીકરણ કરે છે. તેના વિના પણ વિનંતી મેળ ખાય છે, પણ કોડ વાંચનાર આગલી વ્યક્તિએ તે જાતે તારવવું પડે.
નોંધણી એ વ્યાપ્તિની છે જેને અવલોકનની જરૂર છે, સામાન્ય રીતે સ્ક્રીન કે ફોરગ્રાઉન્ડ સેવા. onStop કે onDestroy માં નોંધણી રદ કરો, અને પહેલેથી ગયેલી પ્રવૃત્તિ સાથે callback લટકાવી ન રાખો. દૃશ્ય ઘટક વિનાની એપ કાયમી નિરીક્ષક માટે ખરાબ યજમાન છે, અને જે callbacks ભૂલી જાઓ છો તે જ રૂપરેખાંકન ફેરફાર પછી ક્રેશ થાય છે.
ત્રણ પ્રશ્નો અલગ રાખો
આ ક્ષેત્રની મોટાભાગની ગૂંચવણ ત્રણ અલગ તપાસને એક ગણવાથી આવે છે. તે અલગ API વાપરે છે, અને દરેક સાચી હોઈ શકે જ્યારે બીજી ખોટી હોય.
| 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 |
ત્રીજી પંક્તિ એ છે જે લોકો ક્લાઇન્ટ પર જવાબ આપવા પ્રયત્ન કરે છે, અને ત્યાં જવાબ આપી શકાતો નથી. VPN ક્લાઇન્ટને તેમનો પોતાનો સરનામા સમૂહ આપો અને સર્વર પર સ્રોત સરનામું વાંચો; જ્યારે વપરાશકર્તા સત્રની વચ્ચે ટનલ બદલે ત્યારે ટકી રહેતો આ જ એકમાત્ર પુરાવો છે.
ખોટા પોઝિટિવ દૂર કરતો ચકાસણી ક્રમ
હજી ચલણમાં રહેલો જૂનો નમૂનો કોડ getNetworkInfo(ConnectivityManager.TYPE_VPN) ને બોલાવે છે. એ કૉલ નાપસંદ છે, અને કેટલીક આવૃત્તિઓમાં VPN કનેક્ટ હોવા છતાં તે null પરત કરતો હતો, તેથી ઘણા કોપી કરેલા સ્નિપેટ કામ કરતા ડિવાઇસ પર તૂટેલા દેખાય છે. ક્ષમતા તપાસ એ ફાંસો ટાળે છે અને Android 5.0 થી એકસરખી વર્તે છે. જો તમે એવો કોડબેઝ સાચવો છો જે હજી તેને બોલાવે છે, તો કૉલને fallback માં લપેટવાને બદલે બદલો, કારણ કે fallback જ શરૂઆતમાં ખોટો જવાબ ઉત્પન્ન કર્યો હતો.
એક શોર્ટકટ ચેતવણીને લાયક છે. બાહ્ય સેવા જે જાહેર સરનામું જણાવે છે તેની VPN ના એગ્રેસ સરનામા સાથે તુલના માર્ગ વિશે કંઈક સાબિત કરે છે, પણ દરેક તપાસમાં તૃતીય પક્ષની વિનંતી ઉમેરે છે, એ સેવા ચાલુ રહે તેના પર આધાર રાખે છે, અને તે કેશ થઈ શકે કે બ્લોક થઈ શકે. તેને મેન્યુઅલ નિદાન તરીકે રાખો, ક્યારેય એપની અંદરની સ્થિતિ તપાસ તરીકે નહીં.
આ ક્રમમાં તપાસ ચલાવો અને વપરાશકર્તાના અહેવાલ સાથે ન મળતી પહેલી તપાસ પર અટકો: shell માં ટ્રાન્સપોર્ટ યાદી, સક્રિય નેટવર્કની ક્ષમતાઓ, ટનલ ચાલુ-બંધ કરતી વખતે callback ઘટનાઓ, પછી સર્વર બાજુએ સ્રોત સરનામું. જો ચારેય મળે અને એપ તોપણ ખોટી વર્તે, તો બગ Android ના નેટવર્ક દૃષ્ટિકોણમાં નહીં, તમારા પોતાના સ્થિતિ મશીનમાં છે.