Non, unha aplicación VpnService non pode activar a VPN do teléfono
A aplicación posúe un túnel e o seu ciclo de vida, non o interruptor de VPN do teléfono. O consentimento pódese revogar, só se executa unha VPN á vez, e os paquetes son cousa súa analizalos.
A suposición equivocada é que unha aplicación VpnService acciona un interruptor do sistema e que, a partir de aí, o teléfono queda protexido. O que ocorre en realidade é máis estreito: a aplicación pide consentimento, constrúe unha interface, le e escribe paquetes a través dun descritor de ficheiro, e devolve a interface cando se detén. Só pode haber un túnel así vivo á vez, e o sistema pode quitarllelo sen preguntar. A maior parte do comportamento confuso que a xente lle atribúe ao protocolo vén dese modelo de propiedade.
Trate cada transición do ciclo de vida como parte do deseño e non como un caso límite.
Mito: a aplicación acende a VPN do teléfono
O fluxo comeza con VpnService.prepare(), que devolve un Intent que o usuario debe aceptar, e continúa con establish(), que despois aínda pode fallar por motivos que a aplicación non controla. Establecer un segundo túnel desactiva a primeira interface e substitúe a notificación do sistema. En ningún punto desa secuencia a aplicación posúe un interruptor para todo o dispositivo; posúe o descritor que se lle concedeu e os paquetes que aterran nel. Incluso a notificación persistente pertence ao sistema e non ao deseño da aplicación.
Como a interface se concede en lugar de arrebatarse, outro cliente pode ocupar o oco en calquera momento. A aplicación entérao mediante unha chamada de retorno, non mediante un valor de retorno.
A detención forzada da aplicación vese no panel de notificacións polo mesmo motivo: o sistema informa do que concedeu, non do que a aplicación escolleu mostrar.
Mito: o consentimento dáse unha soa vez
Cando o sistema entrega o túnel a outro cliente, envía unha transacción de revogación no binder que a clase base devolve desde onBind(). Unha aplicación que substitúa ese binder polo seu debe reenviar ela mesma a transacción de revogación, ou VpnService.onRevoke() nunca se disparará e o servizo seguirá escribindo nun descritor que xa non existe. A aprobación tamén a pode retirar o usuario, e o sistema pode deter o servizo durante un reinicio ou unha reconexión sempre activa.
Xestionalo é traballo concreto e non unha liña de rexistro: deixe de ler o descritor, pécheo, limpe o indicador de conectado e dígalle ao usuario en que estado está. Logo decida se a aplicación debe restablecer, preguntar de novo ou esperar, porque nunha configuración sempre activa o sistema pode devolver o servizo por si só.
Unha aplicación que trate a revogación como unha excepción e non como un estado informará de que está conectada mentres cada paquete que escribe se descarta, que é o peor modo de fallo posible para unha ferramenta de privacidade.
Mito: a interface filtra o tráfico por vostede
O que chega é IP en bruto. Capturar ou filtrar significa analizar cabeceiras IP, TCP, UDP e IPv6, seguir fluxos e escribir as respostas de volta ao descritor, o que converte unha aplicación de captura nunha pequena pila de rede e non nunha instalación do sistema. protect() existe para que o socket de transporte da propia aplicación evite o seu túnel en lugar de capturarse a si mesma, e devolve un booleano que merece unha comprobación en cada socket creado despois de que o túnel estea en marcha.
As listas de aplicacións permitidas e prohibidas do construtor deciden de quen entra o tráfico na interface. Non dan acceso á carga útil máis alá dos paquetes IP que a interface transporta, e ningunha API expón o túnel doutro cliente nin enumera os perfís de VPN do sistema. As capacidades de rede poden dicir que unha rede é transporte de VPN, pero non de quen é o túnel.
Por iso as preguntas sobre o estado doutras aplicacións reciben respostas contraditorias: a información simplemente non se expón ao seu proceso.
Que esixe realmente o ciclo de vida
Siga os estados que controla: preparado, establecido, revogado, detido. A reconexión debería ser desmontar e despois establecer, cun único propietario do descritor e do socket de transporte, porque dous compoñentes que compitan por establecer pelexarán polo único oco dispoñible. Os inicios en segundo plano están restrinxidos no Android moderno, así que unha difusión de arranque non é unha garantía; use un servizo en primeiro plano coa súa notificación onde o nivel de API o permita.
Rexistre a transición e non só o estado final, e manteña a máquina de estados o suficientemente pequena para probar todos os camiños. Un estado ao que non pode chegar nunha proba é un estado que atopará no campo sen rexistro.
Probe o ciclo de vida nun dispositivo
Os emuladores poden falsificar a conectividade pero non o camiño de consentimento e revogación de forma convincente, así que execute estes nun dispositivo real cun segundo cliente VPN instalado que roube o oco.
adb shell dumpsys connectivity | grep -i -A3 vpn
adb shell dumpsys activity services | grep -i -A2 vpnservice
adb logcat -s VpnService:V AndroidRuntime:E
adb shell am force-stop com.example.vpnapp
Inicie o túnel, confirme a notificación e a interface, despois conecte o outro cliente e observe se se executa a chamada de retorno de revogación e se o estado se limpa. Deteña a aplicación á forza e comprobe se algo segue informando dun descritor vivo.
Repita a secuencia tras un reinicio sempre activo, porque esa ruta difire dunha conexión iniciada polo usuario. O que busca non é unha icona verde senón a proba de que a aplicación deixou de usar un descritor que xa non posuía.