Зашто ваша Android апликација не може да дода системски VPN профил
VpnService гради тунел који поседује ваша апликација; она не може да додаје или уређује PPTP, L2TP или IPsec уносе телефона. Прођите границу и изаберите прави пут.
Додирнете ред VPN у Подешавањима, видите профил који је инсталирао неко други и почнете да тражите позив који га додаје. Такав позив не постоји. Апликација може да отвори сопствени тунел преко VpnService, али уноси на том списку припадају платформи и оном клијенту који их је створио. Тачно знање где лежи граница штеди вам недељу лова на скривене класе.
Почните од онога што приказује екран Подешавања
Списак VPN је регистар профила које је инсталирао систем или клијент добављача: PPTP, L2TP/IPsec, IKEv2 и сви редови које је гурнуо OEM програм или MDM. Сваки ред носи адресу сервера, акредитиве и имплементацију протокола која живи изван вашег процеса. Када корисник тамо додирне Повежи, тунел подиже клијент платформе, а не ваш код. Зато ред преживи рестарт и зато га деинсталација ваше апликације никада не уклања.
Са корисникове стране списак изгледа као API површина, место где додавање VPN-а треба да буде на удаљености једног интента. Није. Једине јавне улазне тачке које га дотичу су навигациони интенти, а све што у њега пише припада платформи или привилегованој компоненти.
Практична последица: ако текст подршке каже корисницима да додају профил у Подешавањима, ваша апликација уопште није део тог тока.
Шта вам VpnService заправо даје
VpnService и VpnService.Builder описују један тунел који поседује ваша апликација. Додајете адресе, руте, DNS сервере и MTU, ограничавате саобраћај помоћу addAllowedApplication() или addDisallowedApplication(), а затим establish() враћа ParcelFileDescriptor за TUN интерфејс. Од тог тренутка апликација чита IP пакете и пише одговоре, што значи да је протокол ваш да га имплементирате или уградите: OpenVPN, WireGuard, прилагођени транспорт.
Ништа у том следу не говори PPTP, L2TP/IPsec или IKEv2. Builder нема прекидач који каже користи системски L2TP клијент, и нема повратног позива који вам дозвољава да управљате профилом који платформа већ поседује. То је права граница, и то је граница дизајна, а не празнина у дозволама.
Дакле апликација сасвим може бити VPN клијент на Android-у. Само не може бити менаџер за клијенте који долазе са телефоном.
Дијалог пристанка није украс
Пошто ваш тунел може да захвати саобраћај других апликација, систем тражи да га корисник изричито одобри. prepare() враћа Intent који морате да покренете, одобрење је везано за ваш пакет, а док је тунел активан статусна трака приказује сталан индикатор. Други VPN који се подигне деактивира први, јер Android држи један активан VPN у једном тренутку.
То правило једног активног збуњује људе у тестирању. Подигнете свој тунел док је корпоративни клијент повезан и закључите да је ваш код покварен, а платформа се једноставно пребацила са другог клијента. Одобрења се могу касније повући, а prepare() може да врати null на уређајима где нема активности за пристанак, па establish() и даље мора да обрађује неуспех.
Скривени API-ји и интенти подешавања
Старији одговори упућују на com.android.internal класе и AIDL интерфејсе које користи уграђени клијент. Нису у SDK-у, мењају се између издања без најаве, а продавнице апликација третирају тај приступ као ризик. Root-овање уређаја их такође не чини стабилним, јер root и приступ скривеним API-јима су неповезани проблеми.
Подржана навигациона помоћ је Settings.ACTION_VPN_SETTINGS, чија је вредност android.net.vpn.SETTINGS. Разрешите га пре покретања, јер неке OEM градње не испоручују ту активност; пређите на писане кораке када разрешавање не успе. Он води корисника на екран и ништа не конфигурише.
Путеви власника уређаја и MDM-а су изузетак који људи обично мисле. DevicePolicyManager може да одреди пакет стално укљученог VPN-а, а управљане конфигурације могу унапред да учитају подешавања за клијента који их подржава, али то још увек није јавни SDK који пише PPTP профил.
Прођите одлуку са корисникове стране
Ако ваш производ мора да преноси саобраћај, планирајте VpnService плус прави протоколни стек и предвидите време за ток пристанка и правило једног VPN-а. Ако је циљ повезивање са постојећим корпоративним профилом, ваш посао је навођење: дубока веза до екрана подешавања, документовање поља и пустите клијент платформе да ради тунелирање. Ако апликација само треба да достигне приватну крајњу тачку, није јој уопште потребан сопствени тунел.
Запишите ту одлуку пре него што напишете код, јер три пута после првог спринта готово да немају ништа заједничко.
Последња провера пре почетка: каже ли захтев да се повезује наша апликација или да се повезује уређај? Прво је VpnService, друго је профил који не можете да створите. Исправно формулисати ту реченицу јефтиније је од било каквог рефакторисања.