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.
Чтобы обойти эту проблему и выполнить такие операции, как проверка памяти, можно пометить сегменты, предназначенные только для выполнения, как чтение+выполнение, вызвав 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.
- Расширение support_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 и порт сервера. Раньше это необходимо было передавать по внеполосному каналу, например, с помощью обмена сообщениями 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 для получения 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 под управлением 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 пользователь видит эти предупреждения только тогда, когда запускает приложение, которое недавно не обновлялось. Для приложений, распространяемых через другие магазины, в 2019 году вступают в силу аналогичные требования к целевому API. Дополнительные сведения об этих требованиях см. в разделе Расширение требований к целевому уровню 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
.
Zip-файл
В 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 или ниже, этот объект будет правильно прочитан приложениями, ориентированными на уровень 24 или выше, и наоборот.
Изменения java.io.FileChannel.map()
Начиная с Android 10, FileChannel.map()
не поддерживается для нестандартных файлов, таких как /dev/zero
, размер которых нельзя изменить с помощью truncate()
. Предыдущие версии Android проглатывали ошибку, возвращаемую функцией truncate()
, но Android 10 выдает исключение IOException. Если вам нужно старое поведение, вы должны использовать собственный код.