В Android 10 внесены изменения в поведение, которые могут повлиять на ваше приложение. Изменения, перечисленные на этой странице, применяются к вашему приложению при работе на Android 10, независимо от targetSdkVersion приложения. Вам следует протестировать ваше приложение и внести необходимые изменения для корректной работы с этими изменениями.
Если targetSdkVersion вашего приложения равен 29 или выше, вам также потребуется добавить поддержку дополнительных изменений. Для получения подробной информации ознакомьтесь с разделом «Изменения в поведении для приложений, ориентированных на версию 29» .
Примечание: Помимо изменений, перечисленных на этой странице, Android 10 вводит большое количество изменений и ограничений, связанных с конфиденциальностью, в том числе следующие:
- Фоновый доступ к местоположению устройства
- Начинается фоновая активность
- Информация о контактах и интересах
- рандомизация MAC-адреса
- Метаданные камеры
- модель разрешений
Эти изменения затрагивают все приложения и повышают уровень конфиденциальности пользователей. Чтобы узнать больше о том, как поддержать эти изменения, посетите страницу « Изменения в политике конфиденциальности» .
Ограничения интерфейса, не относящиеся к SDK
Для обеспечения стабильности и совместимости приложений платформа начала ограничивать использование не-SDK интерфейсов вашими приложениями в Android 9 (уровень API 28). Android 10 включает обновленные списки ограниченных не-SDK интерфейсов, основанные на сотрудничестве с разработчиками Android и результатах последнего внутреннего тестирования. Наша цель — обеспечить наличие общедоступных альтернатив до того, как мы начнем ограничивать не-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 .
Вы можете определить, привело ли такое поведение к сбою, изучив соответствующий файл удаленных файлов в /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в предыдущих версиях Android выбрасывали исключениеSSLHandshakeException, в Android 10 и более поздних версиях вместо этого они выбрасывали исключениеSSLProtocolException. - Режим 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учитывается при выборе ключа подписи для ответов, содержащих сертификаты. - Непрозрачные ключи подписи, например, из Android Keystore, можно использовать с подписями RSA-PSS в протоколе TLS.
Трансляции Wi-Fi Direct
На Android 10 следующие широковещательные сообщения, связанные с Wi-Fi Direct, не остаются активными:
Если ваше приложение полагалось на получение этих широковещательных сообщений при регистрации, поскольку они были "липкими", используйте соответствующий метод get() при инициализации, чтобы получить эту информацию.
Возможности, поддерживающие Wi-Fi
В Android 10 добавлена поддержка упрощения создания TCP/UDP-сокетов с использованием протоколов передачи данных, поддерживающих Wi-Fi. Для создания TCP/UDP-сокета, подключающегося к ServerSocket , клиентскому устройству необходимо знать IPv6-адрес и порт сервера. Ранее эта информация передавалась внеполосным способом, например, с помощью обмена сообщениями уровня 2 Bluetooth или Wi-Fi, или обнаруживалась внутриполосным способом с использованием других протоколов, таких как 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()
Java
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 для получения 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)
Java
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 отправляет Intent с действием ACTION_MANAGE_OVERLAY_PERMISSION , система автоматически отклоняет запрос и перенаправляет пользователя на экран настроек , где сообщается, что разрешение не разрешено, поскольку замедляет работу устройства. Если приложение на устройстве Go вызывает Settings.canDrawOverlays() , метод всегда возвращает false. Эти ограничения не распространяются на приложения, получившие разрешение SYSTEM_ALERT_WINDOW до обновления устройства до Android 10.
Предупреждения для приложений, ориентированных на более старые версии Android.
Устройства под управлением Android 10 и выше предупреждают пользователей при первом запуске любого приложения, ориентированного на Android 5.1 (уровень API 22) или ниже. Если приложение запрашивает у пользователя разрешение, пользователю также предоставляется возможность изменить разрешения приложения перед его первым запуском.
В связи с требованиями Google Play к целевому API , пользователь видит эти предупреждения только при запуске приложения, которое не обновлялось в последнее время. Для приложений, распространяемых через другие магазины, аналогичные требования к целевому 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() имела тот же эффект, что и передача текущей фабрики по умолчанию .
Библиотека 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, устаревшей функции для инициирования обмена данными между устройствами с помощью технологии ближней бесконтактной связи (NFC). Мы также прекращаем поддержку нескольких связанных с NFC API. Android Beam остается опционально доступным для партнеров-производителей устройств, желающих его использовать, но его активная разработка прекращена. Однако Android продолжит поддерживать другие возможности и API NFC, и сценарии использования, такие как чтение с меток и платежи, будут по-прежнему работать должным образом.
изменение поведения java.math.BigDecimal.stripTrailingZeros()
BigDecimal.stripTrailingZeros() больше не сохраняет конечные нули в качестве особого случая, если входное значение равно нулю.
Изменения в поведении java.util.regex.Matcher и Pattern
Результат функции split() был изменен: теперь он не начинается с пустой String (""), если в начале ввода найдено совпадение нулевой ширины. Это также влияет на String.split() . Например, "x".split("") теперь возвращает {"x"} тогда как раньше в более старых версиях Android возвращалось {"", "x"} . "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() truncate() В предыдущих версиях Android возвращалось исключение errno, но Android 10 выбрасывает исключение IOException. Если вам необходимо использовать старое поведение, вы должны использовать нативный код.