De ce aplicația ta Android nu poate adăuga un profil VPN de sistem
VpnService construiește un tunel care aparține aplicației tale; nu poate adăuga sau edita intrările PPTP, L2TP sau IPsec ale telefonului. Urmează granița și alege calea corectă.
Atingi rândul VPN din Setări, vezi un profil instalat de altcineva și începi să cauți apelul care adaugă unul. Un astfel de apel nu există. O aplicație poate deschide propriul tunel prin VpnService, dar intrările din acea listă aparțin platformei și clientului care le-a creat. Să știi exact unde se află granița îți economisește o săptămână de urmărit clase ascunse.
Începe cu ce arată ecranul Setări
Lista VPN este un registru al profilelor instalate de sistem sau de un client al producătorului: PPTP, L2TP/IPsec, IKEv2 și rândurile împinse de o aplicație OEM sau de un MDM. Fiecare rând poartă o adresă de server, date de autentificare și o implementare de protocol care trăiește în afara procesului tău. Când utilizatorul atinge Conectare acolo, tunelul este ridicat de clientul platformei, nu de codul tău. De aceea rândul supraviețuiește unei reporniri și de aceea dezinstalarea aplicației tale nu îl elimină niciodată.
Din partea utilizatorului lista arată ca o suprafață API, un loc unde adăugarea unui VPN ar trebui să fie la un intent distanță. Nu este. Singurele puncte de intrare publice care o ating sunt intenturi de navigare, iar tot ce scrie în ea aparține platformei sau unei componente privilegiate.
Consecință practică: dacă un text de asistență le spune utilizatorilor să adauge profilul în Setări, aplicația ta nu face deloc parte din acel flux.
Ce îți dă de fapt VpnService
VpnService și VpnService.Builder descriu un tunel care aparține aplicației tale. Adaugi adrese, rute, servere DNS și o MTU, delimitezi traficul cu addAllowedApplication() sau addDisallowedApplication(), iar apoi establish() returnează un ParcelFileDescriptor pentru o interfață TUN. Din acel moment aplicația citește pachete IP și scrie răspunsuri, ceea ce înseamnă că protocolul este al tău de implementat sau încorporat: OpenVPN, WireGuard, un transport propriu.
Nimic din acea secvență nu vorbește PPTP, L2TP/IPsec sau IKEv2. Builder nu are niciun comutator care să spună folosește clientul L2TP al sistemului și nu există niciun callback care să îți permită să conduci un profil pe care platforma îl deține deja. Aceasta este granița reală și este o graniță de proiectare, nu o lipsă de permisiuni.
Deci o aplicație poate fi fără probleme un client VPN pe Android. Doar că nu poate fi un administrator pentru clienții care vin cu telefonul.
Dialogul de consimțământ nu e decor
Deoarece tunelul tău poate captura traficul altor aplicații, sistemul cere ca utilizatorul să îl aprobe explicit. prepare() returnează un Intent pe care trebuie să îl lansezi, aprobarea este legată de pachetul tău, iar cât timp tunelul este activ bara de stare arată un indicator permanent. Un al doilea VPN care urcă îl dezactivează pe primul, pentru că Android rulează un singur VPN activ odată.
Această regulă a unuia activ îi face pe oameni să se împiedice la testare. Ridici tunelul tău în timp ce un client corporate este conectat și concluzionezi că codul tău este stricat, când platforma pur și simplu a comutat de pe celălalt client. Aprobările pot fi revocate mai târziu, iar prepare() poate returna null pe dispozitivele unde lipsește activitatea de consimțământ, așa că establish() tot trebuie să trateze eșecul.
API ascunse și intenturi de setări
Răspunsurile mai vechi indică clase com.android.internal și interfețe AIDL pe care le folosește clientul integrat. Ele nu sunt în SDK, se schimbă între versiuni fără anunț, iar magazinele de aplicații tratează acel acces ca risc. Rootarea dispozitivului nu le face nici ea stabile, pentru că root și accesul la API ascunse sunt probleme nelegate.
Ajutorul de navigare acceptat este Settings.ACTION_VPN_SETTINGS, a cărui valoare este android.net.vpn.SETTINGS. Rezolvă-l înainte de lansare, pentru că unele compilări OEM nu includ această activitate, și treci la pași scriși când rezolvarea eșuează. El duce utilizatorul la ecran și nu configurează nimic.
Căile de proprietar al dispozitivului și MDM sunt excepția la care se referă de obicei oamenii. DevicePolicyManager poate desemna un pachet VPN mereu activ, iar configurațiile gestionate pot preîncărca setări pentru un client care le acceptă, dar asta tot nu este SDK-ul public care scrie un profil PPTP.
Parcurge decizia din partea utilizatorului
Dacă produsul tău trebuie să transporte trafic, planifică VpnService plus o stivă de protocoale reală și bugetează timp pentru fluxul de consimțământ și regula unui singur VPN. Dacă scopul este conectarea la un profil corporate existent, treaba ta este ghidarea: link profund către ecranul de setări, documentarea câmpurilor și lăsarea clientului platformei să facă tunelarea. Dacă aplicația trebuie doar să ajungă la un endpoint privat, nu are nevoie deloc de un tunel propriu.
Scrie acea decizie înainte de a scrie cod, pentru că cele trei căi nu au aproape nimic în comun după primul sprint.
O ultimă verificare înainte de a începe: cerința spune că se conectează aplicația noastră sau că se conectează dispozitivul? Prima este VpnService, a doua este un profil pe care nu îl poți crea. Să formulezi corect acea propoziție costă mai puțin decât orice refactorizare.