Изменения поведения: все приложения

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

Если targetSdkVersion вашего приложения — 29 или выше, вам также потребуется поддержка дополнительных изменений. Обязательно прочтите изменения поведения для приложений, ориентированных на 29, для получения подробной информации.

Примечание: В дополнение к изменениям, перечисленным на этой странице, Android 10 вводит большое количество изменений и ограничений, связанных с конфиденциальностью, включая следующие:

  • Фоновый доступ к местоположению устройства
  • Начинается фоновая активность
  • Информация о близости контактов
  • Рандомизация MAC-адресов
  • Метаданные камеры
  • Модель разрешений

Эти изменения затрагивают все приложения и повышают конфиденциальность пользователей. Чтобы узнать больше о том, как поддержать эти изменения, см. страницу Изменения конфиденциальности .

Ограничения интерфейса, не относящегося к SDK

Чтобы обеспечить стабильность и совместимость приложения, платформа начала ограничивать, какие интерфейсы non-SDK может использовать ваше приложение в Android 9 (уровень API 28). Android 10 включает обновленные списки ограниченных интерфейсов non-SDK, основанные на сотрудничестве с разработчиками Android и последнем внутреннем тестировании. Наша цель — убедиться, что общедоступные альтернативы доступны, прежде чем мы ограничим интерфейсы non-SDK.

Если вы не будете ориентироваться на Android 10 (уровень API 29), некоторые из этих изменений могут не сразу вас затронуть. Однако, хотя вы в настоящее время можете использовать некоторые интерфейсы не SDK ( в зависимости от целевого уровня API вашего приложения ), использование любого метода или поля не SDK всегда несет высокий риск поломки вашего приложения.

Если вы не уверены, использует ли ваше приложение интерфейсы, отличные от SDK, вы можете протестировать его , чтобы узнать. Если ваше приложение использует интерфейсы, отличные от SDK, вам следует начать планировать миграцию на альтернативы SDK. Тем не менее, мы понимаем, что некоторые приложения имеют допустимые варианты использования интерфейсов, отличных от SDK. Если вы не можете найти альтернативу использованию интерфейса, отличного от SDK, для функции в вашем приложении, вам следует запросить новый публичный API .

Чтобы узнать больше, ознакомьтесь с разделами Обновления ограничений интерфейсов, не относящихся к SDK, в Android 10 и Ограничения интерфейсов, не относящихся к SDK .

Навигация с помощью жестов

Начиная с Android 10 пользователи могут включить навигацию жестами по всему устройству. Если пользователь включает навигацию жестами, это влияет на все приложения на устройстве, независимо от того, нацелено ли приложение на уровень API 29. Например, если пользователь проводит пальцем от края экрана, система интерпретирует этот жест как навигацию «Назад», если только приложение специально не переопределяет этот жест для частей экрана.

Чтобы сделать ваше приложение совместимым с навигацией жестами, вам нужно будет расширить содержимое приложения от края до края и соответствующим образом обрабатывать конфликтующие жесты. Для получения информации см. документацию по навигации жестами .

НДК

Android 10 включает следующие изменения NDK.

Общие объекты не могут содержать перемещения текста.

Android 6.0 (уровень API 23) запрещает использование перемещений текста в общих объектах. Код должен быть загружен как есть и не должен быть изменен. Это изменение улучшает время загрузки приложения и безопасность.

SELinux применяет это ограничение к приложениям, ориентированным на Android 10 или выше. Если эти приложения продолжат использовать общие объекты, содержащие перемещения текста, они подвергаются высокому риску поломки.

Изменения в библиотеках Bionic и путях динамического компоновщика

Начиная с Android 10, несколько путей являются символическими ссылками вместо обычных файлов. Приложения, которые полагались на то, что пути являются обычными файлами, могут сломаться:

  • /system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
  • /system/lib/libm.so -> /apex/com.android.runtime/lib/bionic/libm.so
  • /system/lib/libdl.so -> /apex/com.android.runtime/lib/bionic/libdl.so
  • /system/bin/linker -> /apex/com.android.runtime/bin/linker

Эти изменения применяются и к 64-битным вариантам файла, при этом lib/ заменяется на lib64/ .

Для совместимости символические ссылки предоставляются по старым путям. Например, /system/lib/libc.so — это символическая ссылка на /apex/com.android.runtime/lib/bionic/libc.so . Таким образом, dlopen(“/system/lib/libc.so”) продолжает работать, но приложения обнаружат разницу, когда они фактически попытаются проверить загруженные библиотеки, прочитав /proc/self/maps или что-то подобное, что необычно, но мы обнаружили, что некоторые приложения делают это в рамках своего процесса защиты от взлома. Если это так, пути /apex/… следует добавить в качестве допустимых путей для файлов Bionic.

Системные двоичные файлы/библиотеки, отображаемые в память, доступную только для выполнения

Начиная с Android 10, исполняемые сегменты системных двоичных файлов и библиотек отображаются в память только для выполнения (не для чтения) в качестве метода защиты от атак с повторным использованием кода. Если ваше приложение выполняет операции чтения в сегментах памяти, помеченных как только для выполнения (из-за ошибки, уязвимости или преднамеренной проверки памяти), система отправляет сигнал SIGSEGV вашему приложению.

Вы можете определить, вызвало ли это поведение сбой, изучив соответствующий файл tombstone в /data/tombstones/ . Сбой, связанный только с выполнением, содержит следующее сообщение об отмене:

Cause: execute-only (no-read) memory access error; likely due to data in .text.

Чтобы обойти эту проблему для выполнения таких операций, как проверка памяти, можно пометить сегменты только для выполнения как read+execute, вызвав mprotect() . Однако мы настоятельно рекомендуем впоследствии вернуть его в режим только для выполнения, поскольку эта настройка разрешения доступа обеспечивает лучшую защиту для вашего приложения и пользователей.

Безопасность

Android 10 включает следующие изменения безопасности.

TLS 1.3 включен по умолчанию

В Android 10 и выше TLS 1.3 включен по умолчанию для всех подключений TLS. Вот несколько важных деталей о нашей реализации TLS 1.3:

  • Наборы шифров TLS 1.3 не могут быть настроены. Поддерживаемые наборы шифров TLS 1.3 всегда включены, если включен TLS 1.3. Любая попытка отключить их вызовом setEnabledCipherSuites() игнорируется.
  • При согласовании TLS 1.3 объекты HandshakeCompletedListener вызываются до добавления сеансов в кэш сеансов. (В TLS 1.2 и других предыдущих версиях эти объекты вызываются после добавления сеансов в кэш сеансов.)
  • В некоторых ситуациях, когда экземпляры SSLEngine выдают исключение SSLHandshakeException в предыдущих версиях Android, эти экземпляры выдают исключение SSLProtocolException в Android 10 и выше.
  • Режим 0-RTT не поддерживается.

При желании вы можете получить SSLContext , в котором отключен TLS 1.3, вызвав SSLContext.getInstance("TLSv1.2") . Вы также можете включать или отключать версии протокола для каждого соединения, вызывая setEnabledProtocols() для соответствующего объекта.

Сертификаты, подписанные с помощью SHA-1, не являются доверенными в TLS

В Android 10 сертификаты, использующие алгоритм хэширования SHA-1, не являются доверенными в соединениях TLS. Корневые центры сертификации не выпускали такие сертификаты с 2016 года, и им больше не доверяют в Chrome и других основных браузерах.

Любая попытка подключения завершится неудачей, если подключение осуществляется к сайту, представляющему сертификат, использующий SHA-1.

Изменения и улучшения поведения KeyChain

Некоторые браузеры, такие как Google Chrome, позволяют пользователям выбирать сертификат, когда сервер TLS отправляет сообщение с запросом сертификата как часть рукопожатия TLS. Начиная с Android 10, объекты KeyChain учитывают эмитентов и параметры спецификации ключа при вызове KeyChain.choosePrivateKeyAlias() для показа пользователям запроса на выбор сертификата. В частности, этот запрос не содержит вариантов, которые не соответствуют спецификациям сервера.

Если нет доступных для выбора пользователем сертификатов, как в случае, когда ни один сертификат не соответствует спецификации сервера или на устройстве не установлены сертификаты, запрос на выбор сертификата вообще не отображается.

Кроме того, на Android 10 и выше не обязательно иметь блокировку экрана устройства для импорта ключей или сертификатов CA в объект KeyChain .

Другие изменения TLS и криптографии

В библиотеках TLS и криптографии произошло несколько незначительных изменений, которые вступают в силу в Android 10:

  • Шифры AES/GCM/NoPadding и ChaCha20/Poly1305/NoPadding возвращают более точные размеры буфера из getOutputSize() .
  • Набор шифров TLS_FALLBACK_SCSV исключается из попыток подключения с максимальным протоколом TLS 1.2 или выше. Из-за улучшений в реализациях сервера TLS мы не рекомендуем пытаться использовать внешний резервный вариант TLS. Вместо этого мы рекомендуем полагаться на согласование версии TLS.
  • ChaCha20-Poly1305 — это псевдоним для ChaCha20/Poly1305/NoPadding.
  • Имена хостов с точками в конце не считаются допустимыми именами хостов SNI.
  • Расширение supported_signature_algorithms в CertificateRequest учитывается при выборе ключа подписи для ответов сертификатов.
  • С подписями RSA-PSS в TLS можно использовать непрозрачные ключи подписи, например из Android Keystore.

Прямые трансляции Wi-Fi

На Android 10 следующие трансляции, связанные с Wi-Fi Direct, не являются закрепленными:

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

Возможности Wi-Fi Aware

В Android 10 добавлена ​​поддержка для упрощения создания сокетов TCP/UDP с использованием каналов передачи данных Wi-Fi Aware. Чтобы создать сокет TCP/UDP, подключающийся к ServerSocket , клиентскому устройству необходимо знать адрес IPv6 и порт сервера. Ранее это требовалось сообщать вне диапазона, например, с помощью обмена сообщениями BT или Wi-Fi Aware уровня 2, или обнаруживать внутри диапазона с помощью других протоколов, например mDNS. С Android 10 информация может передаваться как часть настройки сети.

Сервер может выполнить одно из следующих действий:

  • Инициализируйте ServerSocket и установите или получите порт, который будет использоваться.
  • Укажите информацию о порте как часть сетевого запроса Wi-Fi Aware.

В следующем примере кода показано, как указать информацию о порте как часть сетевого запроса:

Котлин

val ss = ServerSocket()
val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
  .setPskPassphrase("some-password")
  .setPort(ss.localPort)
  .build()

val myNetworkRequest = NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build()

Ява

ServerSocket ss = new ServerSocket();
WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier
  .Builder(discoverySession, peerHandle)
  .setPskPassphrase(some-password)
  .setPort(ss.getLocalPort())
  .build();

NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build();

Затем клиент выполняет сетевой запрос Wi-Fi Aware, чтобы получить IPv6 и порт, предоставленные сервером:

Котлин

val callback = object : ConnectivityManager.NetworkCallback() {
  override fun onAvailable(network: Network) {
    ...
  }
  
  override fun onLinkPropertiesChanged(network: Network,
      linkProperties: LinkProperties) {
    ...
  }

  override fun onCapabilitiesChanged(network: Network,
      networkCapabilities: NetworkCapabilities) {
    ...
    val ti = networkCapabilities.transportInfo
    if (ti is WifiAwareNetworkInfo) {
       val peerAddress = ti.peerIpv6Addr
       val peerPort = ti.port
    }
  }
  override fun onLost(network: Network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback)

Ява

callback = new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(Network network) {
    ...
  }
  @Override
  public void onLinkPropertiesChanged(Network network,
      LinkProperties linkProperties) {
    ...
  }
  @Override
  public void onCapabilitiesChanged(Network network,
      NetworkCapabilities networkCapabilities) {
    ...
    TransportInfo ti = networkCapabilities.getTransportInfo();
    if (ti instanceof WifiAwareNetworkInfo) {
       WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti;
       Inet6Address peerAddress = info.getPeerIpv6Addr();
       int peerPort = info.getPort();
    }
  }
  @Override
  public void onLost(Network network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback);

SYSTEM_ALERT_WINDOW на устройствах Go

Приложения, работающие на устройствах Android 10 (Go edition), не могут получить разрешение SYSTEM_ALERT_WINDOW . Это связано с тем, что рисование окон наложения использует чрезмерный объем памяти, что особенно вредно для производительности устройств Android с малым объемом памяти.

Если приложение, работающее на устройстве Go Edition под управлением Android 9 или ниже, получает разрешение SYSTEM_ALERT_WINDOW , приложение сохраняет это разрешение даже при обновлении устройства до Android 10. Однако приложения, у которых еще нет такого разрешения, не могут получить его после обновления устройства.

Если приложение на устройстве Go отправляет намерение с действием ACTION_MANAGE_OVERLAY_PERMISSION , система автоматически отклоняет запрос и перенаправляет пользователя на экран настроек , на котором говорится, что разрешение не разрешено, поскольку оно замедляет работу устройства. Если приложение на устройстве Go вызывает Settings.canDrawOverlays() , метод всегда возвращает false. Опять же, эти ограничения не применяются к приложениям, которые получили разрешение SYSTEM_ALERT_WINDOW до обновления устройства до Android 10.

Предупреждения для приложений, предназначенных для старых версий Android

Устройства под управлением Android 10 или выше предупреждают пользователей при первом запуске любого приложения, ориентированного на Android 5.1 (уровень API 22) или ниже. Если приложение требует от пользователя предоставления разрешений, пользователю также предоставляется возможность настроить разрешения приложения, прежде чем приложению будет разрешено запуститься в первый раз.

Из-за требований к целевому API Google Play пользователь видит эти предупреждения только при запуске приложения, которое давно не обновлялось. Для приложений, распространяемых через другие магазины, аналогичные требования к целевому API вступают в силу в 2019 году. Для получения дополнительной информации об этих требованиях см. Расширение требований к целевому уровню API в 2019 году .

Удалены наборы шифров SHA-2 CBC

Следующие наборы шифров SHA-2 CBC были удалены с платформы:

  • TLS_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_256_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

Эти наборы шифров менее безопасны, чем аналогичные наборы шифров, использующие GCM, и большинство серверов либо поддерживают оба варианта этих наборов шифров — GCM и CBC, либо не поддерживают ни один из них.

Использование приложения

В Android 10 внесены следующие изменения в поведение, связанные с использованием приложений:

  • Улучшения использования приложения UsageStats - Android 10 точно отслеживает использование приложения с помощью UsageStats , когда приложения используются в режиме разделенного экрана или «картинка в картинке». Кроме того, Android 10 правильно отслеживает мгновенное использование приложения.

  • Оттенки серого для каждого приложения — Android 10 позволяет устанавливать режим отображения оттенков серого для каждого приложения.

  • Состояние отвлечения внимания для каждого приложения — Android 10 может выборочно устанавливать для приложений «состояние отвлечения внимания», при котором их уведомления подавляются, и они не отображаются в качестве рекомендуемых приложений.

  • Приостановка и воспроизведение . В Android 10 приостановленные приложения не могут воспроизводить звук.

Изменения HTTPS-соединения

Если приложение под управлением Android 10 передает null в setSSLSocketFactory() , возникает IllegalArgumentException . В предыдущих версиях передача null в setSSLSocketFactory() имела тот же эффект, что и передача в текущей default factory .

Библиотека android.preference устарела

Библиотека android.preference устарела в Android 10. Разработчикам следует использовать библиотеку предпочтений AndroidX, часть Android Jetpack . Для получения дополнительных ресурсов, которые помогут в миграции и разработке, ознакомьтесь с обновленным Руководством по настройкам , а также с нашим общедоступным примером приложения и справочной документацией .

Изменения в библиотеке утилит ZIP-файла

Android 10 вносит следующие изменения в классы в пакете java.util.zip , который обрабатывает файлы ZIP. Эти изменения делают поведение библиотеки более согласованным между Android и другими платформами, использующими java.util.zip .

Инфлятор

В предыдущих версиях некоторые методы в классе Inflater выдавали исключение IllegalStateException , если они вызывались после вызова end() . В Android 10 эти методы вместо этого выдают исключение NullPointerException .

ZipFile

В Android 10 и более поздних версиях конструктор ZipFile , принимающий аргументы типа File , int и Charset , не выдает исключение ZipException если предоставленный ZIP-файл не содержит никаких файлов.

ZipOutputStream

В Android 10 и выше метод finish() в ZipOutputStream не выдает исключение ZipException при попытке записать выходной поток для ZIP-файла, который не содержит никаких файлов.

Изменения камеры

Многие приложения, использующие камеру, предполагают, что если устройство находится в портретной конфигурации, то физическое устройство также находится в портретной ориентации, как описано в разделе Ориентация камеры . Это было безопасным предположением в прошлом, но это изменилось с расширением доступных форм-факторов, таких как складные устройства. Это предположение на этих устройствах может привести либо к неправильно повернутому, либо к масштабированному (или и к тому, и к другому) отображению видоискателя камеры.

Приложения, ориентированные на API уровня 24 или выше, должны явно устанавливать android:resizeableActivity и предоставлять необходимую функциональность для обработки многооконного режима.

Отслеживание использования батареи

Начиная с Android 10, SystemHealthManager сбрасывает статистику использования батареи всякий раз, когда устройство отключается после серьезного события зарядки . В общих чертах, серьезное событие зарядки — это либо: Устройство полностью заряжено, либо устройство перешло из состояния почти разряженного в состояние почти заряженного.

До Android 10 статистика использования батареи сбрасывалась всякий раз, когда устройство отключалось от сети, независимо от того, насколько незначительно менялся уровень заряда батареи.

Устаревание Android Beam

В Android 10 мы официально прекращаем поддержку Android Beam, старой функции для инициирования обмена данными между устройствами через Near Field Communication (NFC). Мы также прекращаем поддержку нескольких связанных API NFC. Android Beam остается опционально доступным для партнеров-производителей устройств, которые хотят его использовать, но он больше не находится в активной разработке. Однако Android продолжит поддерживать другие возможности и API NFC, а такие варианты использования, как чтение с тегов и платежи, продолжат работать, как и ожидалось.

Изменение поведения java.math.BigDecimal.stripTrailingZeros()

BigDecimal.stripTrailingZeros() больше не сохраняет конечные нули как особый случай, если входное значение равно нулю.

Изменения поведения java.util.regex.Matcher и Pattern

Результат split() был изменен, чтобы больше не начинаться с пустой String (""), когда в начале ввода есть совпадение нулевой ширины. Это также влияет на String.split() . Например, "x".split("") теперь возвращает {"x"} , тогда как раньше он возвращал {"", "x"} в старых версиях Android. "aardvark".split("(?=a)" теперь возвращает {"a", "ardv", "ark"} вместо {"", "a", "ardv", "ark"} .

Также было улучшено поведение исключений для недопустимых аргументов:

  • appendReplacement(StringBuffer, String) теперь выдает IllegalArgumentException вместо IndexOutOfBoundsException , если заменяющая String заканчивается одиночной обратной косой чертой, что является недопустимым. То же самое исключение теперь выдается, если заменяющая String заканчивается символом $ . Ранее в этом сценарии не выдавалось никаких исключений.
  • replaceFirst(null) больше не вызывает reset() в Matcher , если он выдает NullPointerException . NullPointerException теперь выдается и при отсутствии совпадений. Раньше он выдавался только при наличии совпадений.
  • start(int group) , end(int group) и group(int group) теперь выдают более общее исключение IndexOutOfBoundsException , если индекс группы выходит за пределы. Ранее эти методы выдавали исключение ArrayIndexOutOfBoundsException .

Угол по умолчанию для GradientDrawable теперь TOP_BOTTOM

В Android 10, если вы определяете GradientDrawable в XML и не указываете измерение угла, ориентация градиента по умолчанию будет TOP_BOTTOM . Это изменение по сравнению с предыдущими версиями Android, где по умолчанию было LEFT_RIGHT .

В качестве обходного пути при обновлении до последней версии AAPT2 инструмент устанавливает измерение угла равным 0 для устаревших приложений, если измерение угла не указано.

Ведение журнала для сериализованных объектов с использованием SUID по умолчанию

Начиная с Android 7.0 (API уровня 24) платформа внесла исправление в serialVersionUID по умолчанию для сериализуемых объектов . Это исправление не повлияло на приложения, ориентированные на API уровня 23 или ниже.

Начиная с Android 10, если приложение ориентировано на API уровня 23 или ниже и использует старый, неверный serialVersionUID по умолчанию, система регистрирует предупреждение и предлагает исправить код.

В частности, система регистрирует предупреждение, если выполняются все следующие условия:

  • Приложение рассчитано на API уровня 23 или ниже.
  • Класс сериализован.
  • Сериализованный класс использует serialVersionUID по умолчанию вместо явного задания serialVersionUID .
  • Значение serialVersionUID по умолчанию отличается от значения serialVersionUID , если бы приложение предназначалось для API уровня 24 или выше.

Это предупреждение регистрируется один раз для каждого затронутого класса. Предупреждающее сообщение включает предлагаемое исправление, которое заключается в явной установке serialVersionUID на значение по умолчанию, которое будет вычислено, если приложение нацелено на уровень API 24 или выше. Используя это исправление, вы можете гарантировать, что если объект из этого класса сериализуется в приложении, нацеленном на уровень API 23 или ниже, объект будет правильно прочитан приложениями, нацеленными на уровень API 24 или выше, и наоборот.

Изменения java.io.FileChannel.map()

Начиная с Android 10, FileChannel.map() не поддерживается для нестандартных файлов, таких как /dev/zero , размер которых нельзя изменить с помощью truncate() . Предыдущие версии Android поглощали errno, возвращаемый truncate() , но Android 10 выдает IOException. Если вам нужно старое поведение, вы должны использовать собственный код.