Jy tik op die VPN-ry in Instellings, sien 'n profiel wat iemand anders geïnstalleer het, en begin soek na die oproep wat een byvoeg. Daar is nie so 'n oproep nie. 'n Program kan sy eie tonnel deur VpnService oopmaak, maar die inskrywings in daardie lys behoort aan die platform en aan watter kliënt dit ook al geskep het. Om presies te weet waar die lyn lê, spaar jou 'n week se jaag op verborge klasse.

Begin by wat die Instellings-skerm wys

Die VPN-lys is 'n register van profiele wat die stelsel of 'n handelaar se kliënt geïnstalleer het: PPTP, L2TP/IPsec, IKEv2, en enige rye wat 'n OEM-program of 'n MDM ingestoot het. Elke ry dra 'n bedieneradres, geloofsbriewe en 'n protokolimplementering wat buite jou proses leef. Wanneer die gebruiker daar op Verbind tik, bring die platformkliënt die tonnel op, nie jou kode nie. Dit is waarom die ry 'n herstart oorleef en waarom die verwydering van jou program dit nooit verwyder nie.

Van die gebruiker se kant lyk die lys soos 'n API-oppervlak, 'n plek waar die byvoeg van 'n VPN een opset ver moet wees. Dit is nie. Die enigste openbare ingangspunte wat dit raak, is navigasie-opsette, en alles wat daarin skryf, behoort aan die platform of aan 'n bevoorregte komponent.

Praktiese gevolg: as 'n ondersteuningsdokument gebruikers sê om die profiel in Instellings by te voeg, maak jou program glad nie deel van daardie vloei uit nie.

Wat VpnService werklik aan jou gee

VpnService en VpnService.Builder beskryf een tonnel wat jou program besit. Jy voeg adresse, roetes, DNS-bedieners en 'n MTU by, jy bepaal verkeer met addAllowedApplication() of addDisallowedApplication(), en dan gee establish() 'n ParcelFileDescriptor vir 'n TUN-koppelvlak terug. Van daardie punt af lees die program IP-pakkette en skryf antwoorde, wat beteken die protokol is joune om te implementeer of in te sluit: OpenVPN, WireGuard, 'n pasgemaakte transport.

Niks in daardie reeks praat PPTP, L2TP/IPsec of IKEv2 nie. Builder het geen skakelaar wat sê gebruik die stelsel se L2TP-kliënt nie, en daar is geen terugroep wat jou toelaat om 'n profiel te dryf wat die platform reeds besit nie. Dít is die werklike grens, en dit is 'n ontwerpgrens eerder as 'n gaping in toestemmings.

Dus kan 'n program beslis 'n VPN-kliënt op Android wees. Dit kan net nie 'n bestuurder vir die kliënte wees wat saam met die foon kom nie.

Die toestemmingsdialoog is nie versiering nie

Omdat jou tonnel ander programme se verkeer kan vasvang, maak die stelsel dat die gebruiker dit uitdruklik goedkeur. prepare() gee 'n Intent terug wat jy moet lanseer, die goedkeuring is aan jou pakket gebind, en terwyl die tonnel op is, wys die statusbalk 'n aanhoudende aanduiding. 'n Tweede VPN wat opkom, deaktiveer die eerste, want Android laat een aktiewe VPN op 'n slag loop.

Daardie reël van een-aktief laat mense in toetsing struikel. Jy bring jou tonnel op terwyl 'n korporatiewe kliënt gekonnekteer is en kom tot die gevolgtrekking dat jou kode stukkend is, terwyl die platform bloot van die ander kliënt weggeskakel het. Goedkeurings kan later herroep word, en prepare() kan null teruggee op toestelle waar die toestemmingsaktiwiteit ontbreek, so establish() moet steeds foute hanteer.

Verborge API's en instellings-opsette

Ouer antwoorde wys na com.android.internal-klasse en AIDL-koppelvlakke wat die ingeboude kliënt gebruik. Hulle is nie in die SDK nie, hulle verander sonder kennisgewing tussen vrystellings, en programwinkels beskou daardie toegang as 'n risiko. Om die toestel te root maak hulle ook nie stabiel nie, want root en toegang tot verborge API's is onverwante probleme.

Die ondersteunde navigasiehulp is Settings.ACTION_VPN_SETTINGS, waarvan die waarde android.net.vpn.SETTINGS is. Los dit op voordat jy dit lanseer, want sommige OEM-bouwe lewer daardie aktiwiteit nie; val terug op geskrewe stappe wanneer die oplossing misluk. Dit neem die gebruiker na die skerm en stel niks op nie.

Toestel-eienaar- en MDM-paaie is die uitsondering wat mense gewoonlik bedoel. DevicePolicyManager kan 'n always-on VPN-pakket aanwys, en bestuurde konfigurasies kan instellings vooraf laai vir 'n kliënt wat dit ondersteun, maar dit is steeds nie die openbare SDK wat 'n PPTP-profiel skryf nie.

Stap die besluit van die gebruiker se kant af deur

As jou produk verkeer moet dra, beplan vir VpnService plus 'n werklike protokolstapel, en begroot tyd vir die toestemmingsvloei en die een-VPN-reël. As die doel is om aan 'n bestaande korporatiewe profiel te koppel, is jou werk leiding: diep-skakel na die instellingsskerm, dokumenteer die velde, en laat die platformkliënt die tonnel maak. As die program net 'n private eindpunt moet bereik, het dit glad nie sy eie tonnel nodig nie.

Skryf daardie besluit neer voordat jy kode skryf, want die drie paaie het byna niks in gemeen ná die eerste sprint nie.

'n Laaste kontrole voordat jy begin: sê die vereiste dat ons program koppel, of dat die toestel koppel? Die eerste is VpnService, die tweede is 'n profiel wat jy nie kan skep nie. Om daardie sin reg te kry, is goedkoper as enige herwerk.

Verwante artikels