O kò lè béèrè lọ́wọ́ Android bóyá VPN ti so pọ̀. VpnService kò fi getter fún ipò ìsopọ̀ hàn, àwọn àmì kọ́kọ́rọ́ tí ó wà nínú pẹpẹ ipò ni ètò ń yà, kì í ṣe ohun tí áàpù rẹ lè kà. Ohun tí o lè ṣe ni béèrè ìbéèrè tóóró sí àkójọ ìsopọ̀: nẹ́tíwọ́kì wo ni ìrìn àwọn ohun ìgbàkúrọ́ áàpù yìí ń lò, àti bóyá nẹ́tíwọ́kì yẹn ń gbé gbígbé VPN. Ìtọ́nisọ́nà yìí ń tẹ̀lé àwọn àyẹ̀wò ní ìtẹ̀lé tí ó ń yẹra fún àwọn èsì rere tí kò tọ́, láti pàṣẹ shell lórí ẹ̀rọ dé callback tí o fi ṣiṣẹ́ nínú áàpù.

Yẹ̀wò ẹ̀rọ láti inú shell kí o tó fọwọ́ kan kóòdù áàpù

Kọ́kọ́ gba ipò ìpìlẹ̀. adb shell dumpsys connectivity ń tẹ̀ gbogbo nẹ́tíwọ́kì tí ètò mọ̀ jáde, ẹ̀ka kọ̀ọ̀kan sì ń kọ àwọn gbígbé rẹ̀, nítorí náà nẹ́tíwọ́kì VPN yóò hàn pẹ̀lú VPN nínú àkọsílẹ̀ yẹn. Ka ẹ̀ka nẹ́tíwọ́kì àkọ́kọ́ kí ohunkóhun tó ṣẹlẹ̀, lẹ́yìn náà wá àwọn nẹ́tíwọ́kì mìíràn tí ó ń gbé gbígbé kan náà.

Àwọn èsì méjì ń dáhùn àwọn ìbéèrè ọ̀tọ̀ọ̀tọ̀. Wíwà nẹ́tíwọ́kì VPN kì í ṣe bí áàpù rẹ ń lò ó, àti lórí ẹ̀rọ tí ó ní prófáìlì iṣẹ́ tàbí olùlò kejì, àwọn méjèèjì lè jẹ́ òtítọ́ lẹ́ẹ̀kan náà nígbà tí ìlànà rẹ ń bá íńtánẹ́ẹ̀tì sọ̀rọ̀ tààrà. Ìlà nẹ́tíwọ́kì tí ń ṣiṣẹ́ ni ó ń pinnu ohun tí àwọn sọ́kẹ́ẹ̀tì rẹ ń ṣe.

Béèrè nẹ́tíwọ́kì tí áàpù ń lò

Nínú kóòdù, àyẹ̀wò agbára jẹ́ ìlà mẹ́rin. Béèrè ACCESS_NETWORK_STATE nínú manifest, lẹ́yìn náà fi agbára nẹ́tíwọ́kì tí ń ṣiṣẹ́ wé gbígbé 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);

Ìdáhùn náàóró pẹ̀lú ìmọ̀ọ́nú: ṣé nẹ́tíwọ́kì àkọ́kọ́ áàpù jẹ́ VPN ní báyìí. Kò sọ nípa VPN wo, bóyá ó jẹ́ tìrẹ, tàbí bóyá ọ̀nà abẹ́lẹ̀ dé òpó kejì. Ka true sí “ìrìn ń jáde nípasẹ̀ ọ̀nà abẹ́lẹ̀ kan” kí o sì pa ìṣirò tìrẹ mọ́ lọ́tọ̀. Boolean tí ń túmọ̀ ohun mẹ́ta lẹ́ẹ̀kan ní ìdákẹ́jẹ́ ni ìdí tí ojú ìtòlẹ́sẹẹsẹ fi ń ròyìn VPN gẹ́gẹ́ bí ó ti pa nígbà tí olùlò ń ṣe ìwákiri nípasẹ̀ rẹ̀.

Ní ìdàkejì, tí o bá nílò láti mọ̀ bóyá nẹ́tíwọ́kì VPN kan wà, tún cm.getAllNetworks() ṣe kí o sì dán gbogbo àkójọ agbára wò. Àwọn ìdáhùn méjì yàtọ̀ lórí ẹ̀rọ tí ń mú VPN àrà ọ̀tọ̀ fún áàpù ṣiṣẹ́ tí ń bo àwọn áàpù mìíràn ṣùgbọ́n kì í bo tìrẹ, ìyàtọ̀ yẹn sì ni orísun ọ̀pọ̀lọpọ̀ àwọn ìròyìn àṣìṣe tí ń sọ pé áàpù kò rí VPN tí ó ti ṣí kedere.

Tẹ̀lé àwọn ìyípadà dípò ṣíṣe ìwádìí léraléra

Ìwádìí léraléra pẹ̀lú aago ìwọ̀n kì í ṣe ìrísí tí ó tọ́ fún ìbéèrè yìí, nítorí àwọn ìyípadà ipò ń wá gẹ́gẹ́ bí ìṣẹ̀lẹ̀. Fi ìbéèrè tí ó bá gbígbé VPN mu forúkọsílẹ̀ kí o sì jẹ́ kí ìlànà sọ fún ọ nígbà tí nẹ́tíwọ́kì tí ó bá mu yóò farahàn, pàdánù tàbí yípadà:

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

Nẹ́tíwọ́kì VPN kì í gbé NET_CAPABILITY_NOT_VPN rárá, nítorí náà yíyọkúrò kedere ń ṣàkọsílẹ̀ èrò. Láìsí rẹ̀ ìbéèrè ṣì bá mu, ṣùgbọ́n ẹni tí yóò ka kóòdù lẹ́yìn gbọ́dọ̀ ronú rẹ̀ fúnra rẹ̀.

Ìforúkọsílẹ̀ jẹ́ ti agbègbè tí ó nílò àkíyèsí, ní ọ̀pọ̀ ìgbà ojú-ìwòye tàbí iṣẹ́ iwájú. Yọ ìforúkọsílẹ̀ kúrò nínú onStop tàbí onDestroy, kí o má sì fi callback kọ́ sórí ìṣe tí ó ti lọ. Áàpù tí kò ní ẹ̀yà tí ó hàn kò dára fún olùṣọ́ tí ó wà títí, àwọn callback tí o gbàgbé ni ó ń ṣubú lẹ́yìn ìyípadà ìṣètò.

Pa àwọn ìbéèrè mẹ́ta mọ́ lọ́tọ̀

Ọ̀pọ̀ ìdàrúdàpọ̀ nínú ẹ̀ka yìí ń wá láti inú kíkà àwọn àyẹ̀wò mẹ́ta ọ̀tọ̀ọ̀tọ̀ bí ọ̀kan. Wọ́n ń lo API ọ̀tọ̀ọ̀tọ̀, ọ̀kọ̀ọ̀kan sì lè jẹ́ òtítọ́ nígbà tí àwọn yòókù jẹ́ irọ́.

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

Ìlà kẹta ni ohun tí àwọn ènìyàn ń gbìyànjú láti dáhùn ní ẹ̀gbẹ́ oníbàárà, kò sì ṣeé dáhùn níbẹ̀. Fún àwọn oníbàárà VPN ní àkójọ àdírẹ́sì tiwọn kí o sì ka àdírẹ́sì orísun lórí olùpèsè; ìyẹn ni ẹ̀rí kan ṣoṣo tí ó ń kù nígbà tí olùlò bá yí ọ̀nà abẹ́lẹ̀ padà ní àárín ìpàdé.

Ìtẹ̀lé ìjẹ́rìí tí ó yọ àwọn èsì rere tí kò tọ́ kúrò

Kóòdù àpẹẹrẹ àtijọ́ tí ó ṣì ń kárí ń pe getNetworkInfo(ConnectivityManager.TYPE_VPN). Ìpè yẹn ti di àtijọ́, àti lórí àwọn ìtúsílẹ̀ mélòókan ó ń dá null padà pàápàá nígbà tí VPN ti so pọ̀, ìdí nìyẹn tí ọ̀pọ̀ àwọn àfọwọ́kọ tí a dà fi ń dàbí ẹni tí ó ti bàjẹ́ lórí ẹ̀rọ tí ń ṣiṣẹ́. Àwọn àyẹ̀wò agbára ń yẹra fún okùn yẹn wọ́n sì ń hùwà kan náà láti Android 5.0 síwájú. Tí o bá ń tọ́jú kóòdù tí ó ṣì ń pè é, rọ́pò ìpè náà dípò kíkún ún sínú ipasẹ̀ àbáyọ, nítorí ipasẹ̀ àbáyọ ni ó dá ìdáhùn tí kò tọ́ ní ìbẹ̀rẹ̀.

Ọ̀nà àbáyọ kan yẹ fún ìkìlọ̀. Fífi àdírẹ́sì gbangba tí iṣẹ́ ìta ń ròyìn wé àdírẹ́sì ìjáde VPN ń fi nǹkan kan hàn nípa ọ̀nà, ṣùgbọ́n ó ń fi ìbéèrè ẹ̀ka kẹta kún gbogbo àyẹ̀wò, ó sinmi lórí pé iṣẹ́ yẹn wà ní ìṣiṣẹ́, ó sì lè jẹ́ kíkó sínú káṣì tàbí dí. Pa á mọ́ gẹ́gẹ́ bí àyẹ̀wò àfọwọ́, kì í ṣe àyẹ̀wò ipò nínú áàpù rárá.

Ṣe àwọn àyẹ̀wò ní ìtẹ̀lé yìí kí o sì dúró ní èyí àkọ́kọ́ tí kò bá ìròyìn olùlò mu: àkọsílẹ̀ gbígbé láti shell, agbára nẹ́tíwọ́kì tí ń ṣiṣẹ́, àwọn ìṣẹ̀lẹ̀ callback nígbà tí o ń tan ọ̀nà abẹ́lẹ̀ tàn tàbí pa á, lẹ́yìn náà àdírẹ́sì orísun ní ẹ̀gbẹ́ olùpèsè. Tí gbogbo mẹ́rin bá bá ara wọn mu tí áàpù ṣì ń hùwà tí kò tọ́, àṣìṣe wà nínú ẹ̀rọ ipò tìrẹ, kì í ṣe nínú ojú Android lórí nẹ́tíwọ́kì.

Àwọn àpilẹ̀kọ tó jọra