Android игнорирует нажатие подтверждения VPN? Сначала проверьте оверлей
Кнопка согласия, которая не принимает нажатие, обычно означает локальное препятствие для касания, а не сбой сервера или аккаунта. Уберите оверлей и сохраните защиту.
Вы нажимаете кнопку подтверждения VPN, а диалог не реагирует. Естественный вывод — VPN-приложение или сервер сломаны, поэтому люди сбрасывают пароли, меняют DNS или переустанавливают клиент. Обычно ничто из этого не касается неисправности, потому что Android отбрасывает касания, приходящие через препятствие, а экран подтверждения VPN — как раз такая чувствительная подсказка согласия, которая получает эту защиту. Нажатие никогда не доходит до кнопки.
Что на самом деле отклоняет защита
Android защищает чувствительные взаимодействия от tapjacking, когда другое окно находится поверх диалога и либо перехватывает нажатие, либо делает его неоднозначным. Представление подключает это через View.setFilterTouchesWhenObscured, и событие приходит с MotionEvent.FLAG_WINDOW_IS_OBSCURED, когда другое окно помечено как частично или полностью его перекрывающее. Когда это происходит, событие отбрасывается, а не доставляется не туда. Android 12 (API 31) расширил ту же защиту блокировкой недоверенных касаний в системных поверхностях согласия, поэтому диалог подтверждения может отказать в нажатии из оверлея, которое другие приложения всё ещё приняли бы.
Три вещи регулярно создают препятствие: приложение с разрешением показывать поверх других приложений, служба доступности, рисующая содержимое, и плавающий виджет от средства записи экрана или инструмента фильтрации. Некоторые функции экрана производителя добавляют собственный слой, поэтому один и тот же диалог может вести себя по-разному на двух телефонах с одной версией Android. Частично перекрывающее окно устанавливает FLAG_WINDOW_IS_PARTIALLY_OBSCURED, и касание отбрасывается ещё до того, как кнопка его увидит. Это свойство экрана, а не сети. В момент отбрасывания нажатия на сервер VPN ничего не отправлено, поэтому никакое изменение на стороне сервера не может повлиять на результат.
Отделите мёртвое нажатие от неудачного подключения
Это различие и есть весь диагноз, и оно занимает десять секунд. Если нажатие игнорируется, а диалог остаётся точно таким же, препятствие локальное. Если диалог закрывается и после этого появляется ошибка, согласие было принято, и вы перешли на другой этап, которому нужна собственная информация о событиях VPN-приложения.
Локальное прочтение можно подтвердить, проверив, пыталось ли запрашивающее приложение вообще подключиться. Клиент, который ни разу не зафиксировал попытку рукопожатия, пока диалог согласия на экране, не дошёл до сети.
adb shell cmd appops get com.example.vpn SYSTEM_ALERT_WINDOW
adb shell settings get secure enabled_accessibility_servicesПеречислите, у кого есть разрешение на оверлей и какие службы доступности включены, затем сопоставьте это с тем, что работает. Не отключайте саму защиту платформы; именно она не даёт скрытому окну ответить на запрос согласия от вашего имени.
Уберите препятствие и повторите обычный сценарий
Сначала определите приложение, запросившее подтверждение VPN, чтобы знать, какое согласие вы даёте. Затем остановите конкретный оверлей через его собственные настройки, а не отзывая широкое разрешение, которое может понадобиться позже. У экранного фильтра обычно есть переключатель в самом приложении; у плавающего виджета есть элемент закрытия; у режима экрана производителя есть переключатель в настройках экрана.
После этого вернитесь в VPN-приложение и запросите подтверждение снова, чтобы диалог создался заново. Если нажатие теперь работает, настройте поведение совместимости оверлея или оставьте его выключенным на время подключения и сохраните защиту касаний включённой.
Если не удаётся понять, какое окно отвечает за проблему, убирайте их по одному и повторяйте диалог согласия после каждого изменения. Панель управления записывающего устройства или плавающий ярлык — обычный виновник, и то, что вы убрали непосредственно перед успехом, и есть ответ.
Верните всё постороннее, что вы отключили по пути. Экранный фильтр или ночной режим не враг; враг — конкретное окно, перекрывающее диалог.
Чего не стоит делать, чтобы обойти диалог
Не давайте доступ к специальным возможностям незнакомому приложению, чтобы оно могло нажать кнопку, и не устанавливайте для этого вспомогательное приложение. Они дают ровно ту возможность, которую защита призвана не дать, на экране, который авторизует VPN.
Не автоматизируйте диалог инструментом ввода. Это даёт тот же результат, что и вредоносный оверлей, и ничему не учит насчёт причины.
На управляемом устройстве политика, ограничивающая изменения VPN, — решение администратора. Эксперимент с оверлеем не является разрешением обходить её. Равным образом, не реагирующая кнопка согласия — не повод ослаблять проверку сертификата или менять учётные данные: ни одна из настроек не убирает локальное препятствие для касания.
Если всё равно не работает, опишите точное поведение
Описывайте диалог, а не вывод: какое приложение запросило подтверждение, остался ли диалог открытым или закрылся, игнорируют ли нажатия другие чувствительные подсказки, например предупреждения о неизвестных источниках или о специальных возможностях, модель устройства и версию Android, а также снятые вами списки оверлеев и служб доступности.
Пока вы там, задайте владельцу поддержки ещё один вопрос: ограничивает ли политика устройства изменения конфигурации VPN вообще. Управляемая блокировка выглядит иначе, чем проигнорированное нажатие, и понимание того, с чем вы имеете дело, экономит второй круг.
Этот набор отличает проблему перекрытого касания от сломанного устройства ввода, зависшего диалога или блокировки политикой. Он также подсказывает следующему человеку, смотреть ли на экран или на сеть.
Рекомендации Android по tapjacking описывают условия перекрытых окон и API, стоящие за этим поведением. Если нужен след доказательств, ищите FLAG_WINDOW_IS_OBSCURED и FLAG_WINDOW_IS_PARTIALLY_OBSCURED в событии, которое так и не дошло до кнопки. Диалог, который остаётся открытым, и нужно зафиксировать, потому что он показывает: нажатие было удержано, а не передано другому окну.