Запрет на открытый HTTP
Ошибка net::ERR_CLEARTEXT_NOT_PERMITTED встречается в приложениях Android и во встроенных просмотрщиках веб-страниц. Она означает, что приложение попыталось загрузить адрес по протоколу http без шифрования, а политика безопасности не разрешает передачу данных открытым текстом.
Начиная с определённых версий Android разрешение на открытый трафик по умолчанию выключено, если приложение ориентируется на современные версии платформы. Смысл в том, чтобы данные не уходили по сети в читаемом виде, где их может увидеть или изменить любой посредник. Так что это осознанное требование системы, а не неисправность.
Где встречается
У разработчиков — при тестировании приложения, которое обращается к серверу по http на локальной машине или тестовом стенде. Также при загрузке в WebView старой страницы, ссылки внутри которой ведут на http-адреса.
У пользователей — в приложениях, которые не обновлялись и используют старые адреса, а также при переходе по ссылкам, где вместо https указан http. Если приложение открывает встроенную страницу с внешним ресурсом, отказ может выглядеть как пустое окно с сообщением об ошибке.
Как проверить: net
Посмотрите на адрес, который загружает приложение: начинается ли он с http. Попробуйте открыть тот же адрес в обычном браузере: многие сайты сейчас перенаправляют на https, и тогда достаточно указать защищённый вариант.
Для разработчика полезно сверить, для каких доменов и в каких сборках разрешён открытый трафик: в манифесте приложения есть атрибут, а в отдельном файле конфигурации сетевой безопасности можно перечислить исключения. Проверьте, что нужная конфигурация подключена именно к той сборке, которую вы запускаете.
Как исправить правильно
Лучший путь — перевести сервер на HTTPS и использовать адреса со схемой https. Получите сертификат для домена и настройте перенаправление с http. Тогда никакие исключения в приложении не потребуются, а данные будут защищены.
Если речь о тестовой среде, разрешайте открытый трафик точечно, только для нужных доменов и только в отладочной сборке, через файл конфигурации сетевой безопасности. Не включайте глобальное разрешение в рабочей версии приложения: это ослабляет защиту всех соединений.
Пользователю остаётся обновить приложение или обратиться к разработчику: изменить поведение самой программы обычными настройками нельзя.
На что обратить внимание
Если ошибка возникла у приложения, которое раньше работало, вероятно, оно обновилось до сборки, ориентированной на новую версию Android, либо сервер перестал принимать https-перенаправления. Проверьте, доступен ли сайт по защищённому адресу без ошибок сертификата.
Учтите и обратное: у устройства сертификат сайта может быть не принят из-за неверной даты. Убедитесь, что время и часовой пояс на телефоне выставлены автоматически. Если вы тестируете приложение на эмуляторе с локальным сервером, помните, что адрес хост-машины отличается от localhost внутри эмулятора, и проверяйте его отдельно.
Настройка исключений безопасно и по-взрослому
Разработчику полезно знать, как устроена конфигурация сетевой безопасности: это отдельный файл ресурсов, где описываются домены и правила для них. Можно разрешить открытый трафик для конкретного домена, например тестового сервера в локальной сети, и оставить запрет для остальных. Файл подключается атрибутом в манифесте приложения.
В рабочей сборке такой файл лучше не содержать разрешений для внешних доменов вообще. Если один из внешних сервисов не поддерживает шифрование, стоит рассмотреть его замену, а не отказ от защиты.
Отдельно проверьте библиотеки: сторонние компоненты иногда внутри используют адреса со схемой http, и запрет проявляется в них. Обновите библиотеку до версии с защищённым доступом. Тестируйте приложение на реальных устройствах с разными версиями Android, ведь поведение по умолчанию зависит от целевой версии платформы.
Если вы получаете ссылки из внешних источников, приводите их к защищённой схеме перед загрузкой, а при невозможности сообщайте пользователю понятное объяснение. Это лучше, чем показывать внутренний код ошибки и оставлять человека без подсказки.