Android 8: Недоступен HTTP-трафик Cleartext

У меня были сообщения от пользователей с Android 8, что мое приложение (использующее back-end feed) не показывает контент. После расследования я обнаружил, что Exception происходит на Android 8:

08-29 12:03:11.246 11285-11285/ E/: [12:03:11.245, main]: Exception: IOException java.io.IOException: Cleartext HTTP traffic to * not permitted
at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:115)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:458)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.doConnection(AbstractHttpAsyncTask.java:207)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.extendedDoInBackground(AbstractHttpAsyncTask.java:102)
at com.deiw.android.generic.tasks.AbstractAsyncTask.doInBackground(AbstractAsyncTask.java:88)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)

(Я удалил имя пакета, URL и другие возможные идентификаторы)

На Android 7 и ниже все работает, я не устанавливаю android:usesCleartextTraffic в Manifest (и установка его в true не помогает, это значение по умолчанию), я также не использую информацию о сетевой безопасности. Если я вызываю NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted(), он возвращает false для Android 8, true для старой версии, используя тот же файл apk. Я попытался найти упоминание об этом в информации Google об Android O, но безуспешно.

Ответы

Ответ 1

Согласно конфигурации безопасности сети -

Начиная с Android 9 (уровень API 28), поддержка открытого текста по умолчанию отключена.

Также посмотрите на - https://koz.io/android-m-and-the-war-on-cleartext-traffic/

Опция 1 -

Создать файл res/xml/network_security_config.xml -

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">Your URL(ex: 127.0.0.1)</domain>
    </domain-config>
</network-security-config>

AndroidManifest.xml -

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config"
        ...>
        ...
    </application>
</manifest>

Вариант 2 -

Android: использует CleartextTraffic Doc

AndroidManifest.xml -

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>

Также как ответ @david.s указал на android:targetSandboxVersion может быть проблемой -

Согласно Манифесту Документов -

android:targetSandboxVersion

Целевая песочница для этого приложения. Чем выше номер версии песочницы, тем выше уровень безопасности. Его значение по умолчанию равно 1; Вы также можете установить его на 2. Установка этого атрибута на 2 переключает приложение в другую изолированную программную среду SELinux. Следующие ограничения применяются к песочнице уровня 2:

  • Значение по умолчанию для usesCleartextTraffic в конфигурации сетевой безопасности равно false.
  • Обмен UID не разрешен.

Итак, Вариант 3 -

Если у вас есть android:targetSandboxVersion в <manifest> уменьшите его до 1

AndroidManifest.xml -

<?xml version="1.0" encoding="utf-8"?>
<manifest android:targetSandboxVersion="1">
    <uses-permission android:name="android.permission.INTERNET" />
    ...
</manifest>

Ответ 2

В AndroidManifest я нашел этот параметр:

android:networkSecurityConfig="@xml/network_security_config"

и @xml/network_security_config определены в network_security_config.xml как:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!--Set application-wide security config using base-config tag.-->
    <base-config cleartextTrafficPermitted="false"/>
</network-security-config>  

только что я изменил cleartextTrafficPermitted на true

Ответ 3

Возможно, вы захотите разрешить открытый текст только во время отладки, но сохраните преимущества безопасности от отклонения открытого текста в процессе производства. Это полезно для меня, потому что я тестирую свое приложение на сервере разработки, который не поддерживает https. Вот как применить https в производственной среде, но разрешить открытый текст в режиме отладки:

В build.gradle:

// Put this in your buildtypes debug section:
manifestPlaceholders = [usesCleartextTraffic:"true"]

// Put this in your buildtypes release section
manifestPlaceholders = [usesCleartextTraffic:"false"]

В теге приложения в AndroidManifest.xml

android:usesCleartextTraffic="${usesCleartextTraffic}"

Ответ 4

Моя проблема в Android 9 заключалась в навигации по веб-сайтам по доменам с http. Решение из этого ответа

<application 
    android:networkSecurityConfig="@xml/network_security_config"
    ...>

а также:

Рез /XML/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

Ответ 5

Измените ваш URL с HTTP на HTTPS;

Это работает !!!

Ответ 6

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">***Your URL(ex: 127.0.0.1)***</domain>
    </domain-config>
</network-security-config>

В приведенном выше предложении я предоставлял свой URL как http://xyz.abc.com/mno/

Я изменил это на xyz.abc.com, после чего он начал работать.

Ответ 7

В своем файле манифеста добавьте это свойство в тег приложения и очистите проект и запустите приложение, надеюсь, оно будет работать нормально.

  <manifest ...>
  <uses-permission android:name="android.permission.INTERNET" />
  <application
    ...
    android:usesCleartextTraffic="true"
    ...>
    ...
  </application>
  </manifest>

Ответ 8

Это может быть полезно для кого-то.

Недавно у нас была такая же проблема для Android 9, но нам нужно было отображать некоторые URL-адреса в WebView, ничего особенного. Поэтому добавление android:usesCleartextTraffic="true" для Manifest работал, но мы не хотели нарушать безопасность всего приложения для этого. Таким образом, исправление заключалось в изменении ссылок с http на https

Ответ 9

Хорошо, это ⇒⇒ НЕ repeat тысячи повторений добавления его в ваш манифест, но подсказка, которая основывается на этом, но дает вам дополнительное преимущество (и, возможно, некоторую справочную информацию).

Android имеет своего рода функцию перезаписи для src-Directory.

По умолчанию у вас есть

/app/src/main

Но вы можете добавить дополнительные каталоги, чтобы перезаписать ваш AndroidManifest.xml. Вот как это работает:

  • Создайте каталог /app/src/debug
  • Внутри создайте AndroidManifest.xml

Внутри этого файла вам не нужно помещать в него все правила, а только те, которые вы хотите перезаписать из вашего /app/src/main/AndroidManifest.xml

Вот пример того, как это выглядит для запрошенного CLEARTEXT-Permission:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.yourappname">

    <application
            android:usesCleartextTraffic="true"
            android:name=".MainApplication"
            android:label="@string/app_name"
            android:icon="@mipmap/ic_launcher"
            android:allowBackup="false"
            android:theme="@style/AppTheme">
    </application>

</manifest>

С этим знанием теперь легко, как 1,2,3, перегрузить ваши разрешения в зависимости от вашей отладки | главная | освободить окружающую среду.

Большая выгода от этого... у вас нет отладочных материалов в вашем производственном манифесте, и вы сохраняете простую и легкую в обслуживании структуру

Ответ 10

Для проектов React Native

Это было уже исправлено на RN 0,59. Вы можете найти при обновлении diff с 0.58.6 до 0.59. Вы можете применить его без обновления версии RN, выполнив следующие действия:

Создать файлы:

android/app/src/debug/res/xml/react_native_config.xml -

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="false">localhost</domain>
    <domain includeSubdomains="false">10.0.2.2</domain>
    <domain includeSubdomains="false">10.0.3.2</domain>
  </domain-config>
</network-security-config>

android/app/src/debug/AndroidManifest.xml -

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools">

  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

  <application tools:targetApi="28"
      tools:ignore="GoogleAppIndexingWarning" 
      android:networkSecurityConfig="@xml/react_native_config" />
</manifest>

Проверьте принятый ответ, чтобы узнать причину.

Ответ 11

Хорошо, я понял это. Это связано с параметром Manifest android:targetSandboxVersion="2", который я добавил, потому что у нас также есть версия Instant App - он должен быть уверен, что после того, как пользователь обновит приложение Instant App до обычного приложения, он не потеряет свои данные с помощью перечислить. Однако, поскольку неопределенное описание предполагает:

Указывает целевую песочницу, которую приложение хочет использовать. Более высокие версии sanbox будут иметь повышенный уровень безопасности.

Значение по умолчанию для этого атрибута равно 1.

Очевидно, это также добавляет новый уровень безопасности, по крайней мере, на Android 8.

Ответ 12

Добавьте это свойство только в свои заявления

<application
 . 
 android:usesCleartextTraffic="true"
 .

 >

 </application>

Ответ 13

В следующем примере разрешен сквозной трафик во всех доменах. Ключом к этому является <base-config cleartextTrafficPermitted="true"/>, все остальное просто для контекста.

<network-security-config>
   <base-config cleartextTrafficPermitted="true"/>
   <debug-overrides>
      <trust-anchors>
         <certificates src="system" />
         <certificates src="user" />
      </trust-anchors>
   </debug-overrides>
</network-security-config>

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
   <uses-permission android:name="android.permission.INTERNET" />
   <application
       ...
       android:networkSecurityConfig="@xml/network_security_config"
   ...>
   ...
   </application>
</manifest>

Ответ 14

Чтобы применить эти различные ответы к Xamarin.Android, вы можете использовать атрибуты уровня класса и сборки по сравнению с ручным редактированием AndroidManifest.xml

Разумеется, необходимо интернет-разрешение (дух..):

[assembly: UsesPermission(Android.Manifest.Permission.Internet)]

Примечание. Обычно атрибуты уровня сборки добавляются в файл AssemblyInfo.cs, но работает любой файл ниже namespace using и выше.

Затем в своем подклассе Application (при необходимости создайте его) вы можете добавить NetworkSecurityConfig со ссылкой на файл Resources/xml/ZZZZ.xml:

#if DEBUG
[Application(AllowBackup = false, Debuggable = true, NetworkSecurityConfig = "@xml/network_security_config")]
#else
[Application(AllowBackup = true, Debuggable = false, NetworkSecurityConfig = "@xml/network_security_config"))]
#endif
public class App : Application
{
    public App(IntPtr javaReference, Android.Runtime.JniHandleOwnership transfer) : base(javaReference, transfer) { }
    public App() { }

    public override void OnCreate()
    {
        base.OnCreate();
    }
}

Создайте файл в папке Resources/xml (при необходимости создайте папку xml).

Пример файла xml/network_security_config, при необходимости измените его (см. Другие ответы)

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
          <domain includeSubdomains="true">www.example.com</domain>
          <domain includeSubdomains="true">notsecure.com</domain>
          <domain includeSubdomains="false">xxx.xxx.xxx</domain>
    </domain-config>
</network-security-config>

Вы также можете использовать параметр UsesCleartextTraffic в ApplicationAttribute:

#if DEBUG
[Application(AllowBackup = false, Debuggable = true, UsesCleartextTraffic = true)]
#else
[Application(AllowBackup = true, Debuggable = false, UsesCleartextTraffic = true))]
#endif

Ответ 15

Я также получил ту же ошибку "HTTP-трафик в незашифрованном виде запрещен" при разработке моего приложения. Я использую Retrofit2 для сетевых вызовов в моем приложении, и у меня есть две проектные среды (разработка и производство). Мой производственный домен имеет сертификат SSL с вызовами HTTPS, а у dev не будет https. Конфигурация добавлена в версии сборки. Но когда я перехожу на dev, эта проблема сработает. Поэтому я добавил ниже решение для этого.

Я добавил открытый трафик в манифест

 android:usesCleartextTraffic="true"

Затем я добавил спецификацию соединения во время создания класса конфигурации OKHttp.

 .connectionSpecs(CollectionsKt.listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT))

Полное создание OkHttpClient приведено ниже

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .readTimeout(10, TimeUnit.SECONDS)
        .connectTimeout(10, TimeUnit.SECONDS)
        .cache(null)
        .connectionSpecs(CollectionsKt.listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT))
        .addInterceptor(new NetworkInterceptor(context))
        .addInterceptor(createLoggingInterceptor())
        .addInterceptor(createSessionExpiryInterceptor())
        .addInterceptor(createContextHeaderInterceptor())
        .build();

Ответ 16

Измените ваш URL с HTTP на HTTPS;

Ответ 17

добавление этого параметра в заголовок решило мою проблему в ApiSauce React Native

"Content-Type": "application/x-www-form-urlencoded",
  Accept: "application/json"

Ответ 18

Обновление до React Native 0.58.5 или выше. У них есть includeSubdomain в их файлах конфигурации в RN 0.58.5.

ChangeLog

В Rn 0.58.5 они объявили network_security_config со своим доменом сервера. Конфигурация безопасности сети позволяет приложению разрешать трафик открытым текстом из определенного домена. Поэтому не нужно прилагать дополнительных усилий, объявив android:usesCleartextTraffic="true" в теге приложения вашего файла манифеста. Это будет решено автоматически после обновления версии RN.

Ответ 19

Начиная с Android 9.0 (уровень API 28), поддержка открытого текста по умолчанию отключена. Вариант 1 - Создать файл res/xml/network_security_config.xml -

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">Your URL(ex: 127.0.0.1)</domain>
    </domain-config>
</network-security-config>

AndroidManifest.xml -

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config"
        ...>
        ...
    </application>
</manifest>

Вариант 2 - AndroidManifest.xml -

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>

Ответ 20

После изменения API версии 9.0 получение сообщения об ошибке HTTP в открытом виде в YOUR-API.DOMAIN.COM не разрешено (targetSdkVersion = "28"). в xamarin, xamarin.android и андроид студии.

Два шага для устранения этой ошибки в xamarin, xamarin.android и android studio.

Шаг 1. Создайте файловые ресурсы /xml/network_security_config.xml

В network_security_config.xml

<?xml version="1.0" encoding="utf-8" ?>
<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">mobapi.3detrack.in</domain>
  </domain-config>
</network-security-config>

Шаг 2. Обновите AndroidManifest.xml -

Добавьте android: networkSecurityConfig = "@xml/network_security_config" в тег приложения. например:

<application android:label="your App Name" android:icon="@drawable/icon" android:networkSecurityConfig="@xml/network_security_config">

Ответ 21

В моем случае этот URL также не работает в браузере.

Я проверяю с https://www.google.com/

webView.loadUrl("https://www.google.com/")

И это сработало для меня.

Ответ 22

Просто добавьте android: usingCleartextTraffic = "true" внутри файла AndroidManifest.xml