Защо вашето приложение за 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, второто е профил, който не можете да създадете. Да формулирате това изречение правилно е по-евтино от всеки рефакторинг.