В Android 17 есть изменения, которые могут повлиять на работу вашего приложения.
Они касаются всех приложений, запущенных на устройствах с Android 17, независимо от targetSdkVersion. Протестируйте приложение и при необходимости измените его, чтобы оно поддерживало эти изменения.
Также ознакомьтесь со списком изменений в поведении, которые затрагивают только приложения для Android 17.
Основные функции
В Android 17 (уровень API 37) внесены изменения, которые модифицируют или расширяют различные основные возможности системы Android.
Ограничения памяти для приложений
В Android 17 вводятся ограничения на использование памяти приложениями в зависимости от общего объема ОЗУ устройства. Это позволит создать более стабильную и детерминированную среду для приложений и пользователей Android. Эти ограничения направлены на утечки памяти и другие проблемы, которые могут привести к нестабильной работе системы, например к задержкам в интерфейсе, повышенному расходу заряда батареи и принудительному закрытию приложений. Мы ожидаем, что это изменение практически не повлияет на большинство сеансов в приложениях, но рекомендуем следовать советам по работе с памятью, в том числе установить базовый уровень использования памяти.
Чтобы узнать, повлияло ли это на сеанс приложения, вызовите getDescription в ApplicationExitInfo. Если приложение затронуто, причиной выхода будет REASON_OTHER, а описание будет содержать строку "MemoryLimiter:AnonSwap" и другую информацию. Вы также можете использовать профилирование на основе триггеров с TRIGGER_TYPE_ANOMALY, чтобы получать дампы кучи, собранные при достижении лимита памяти.
В документации Управление памятью приложения вы найдете информацию, которая поможет вам диагностировать проблемы с памятью в приложении и оптимизировать потребление ресурсов.
Проверьте, как приложение работает в условиях ограниченной памяти
Вы можете использовать Android Debug Bridge (adb), чтобы изменить или отключить ограничения памяти на любом устройстве, где они действуют. Команда оболочки am предоставляет три подкоманды для настройки ограничений памяти. (Эти команды не действуют на устройствах, где нет ограничений по памяти.)
am memory-limiter ignore <uid>|none|allam memory-limiter manual <pid> <limit>|max|noneam memory-limiter status
ignoreУказывает ограничителю памяти игнорировать некоторые или все процессы. Если передать UID (идентификатор пользователя Android), то ограничитель памяти не будет применять меры ко всем процессам, связанным с этим UID. Вы также можете передать
all(игнорировать все приложения) илиnone(не игнорировать приложения). Передачаnoneпереопределяет все предыдущие вызовыam memory-limiter ignore.Если вы настроите ограничитель памяти так, чтобы он игнорировал UID, вы все равно сможете вручную применить ограничение памяти к процессу в приложении, вызвав
am memory-limiter manual.manualУказывает системе на необходимость ограничить объем памяти для процесса с заданным идентификатором процесса (PID). Ограничение памяти указывается в виде целого числа мегабайт. Например, значение
30означает, что процессу выделяется не более 30 МБ памяти. Если передатьmax, все ограничения на использование памяти для этого процесса будут сняты. Если передать значениеnone, будут удалены все ограничения, заданные вручную, и восстановлены ограничения по умолчанию (если они есть).statusСообщает текущий статус ограничителя памяти. Статус включает ограничения памяти, наложенные на видимые и невидимые процессы.
Конфиденциальность
В Android 17 внесены следующие изменения, направленные на повышение конфиденциальности пользователей.
Защита одноразовых кодов из SMS
Начиная с Android 17, в ОС расширена защита SMS с одноразовыми кодами.
В предыдущих версиях Android эта защита в основном была сосредоточена на формате SMS Retriever. Доставка сообщений, содержащих хеш для извлечения SMS, задерживалась для большинства приложений на три часа. Однако некоторые приложения (например, обработчик SMS по умолчанию) и приложение, которому принадлежал хеш, были освобождены от задержки.
Начиная с Android 17, защита также применяется к сообщениям в формате WebOTP. Если у приложения есть разрешение на чтение SMS-сообщений, но оно не является получателем сообщения WebOTP (что определяется проверкой домена), сообщение будет недоступно для приложения в течение трех часов после его получения. Это изменение призвано повысить безопасность пользователей, гарантируя, что только приложения, связанные с доменом, указанным в сообщении, могут программно считывать код подтверждения.
В течение этого времени трансляция SMS_RECEIVED_ACTION задерживается, а запросы к базе данных поставщика SMS фильтруются. По истечении этого времени SMS-сообщение становится доступно этим приложениям. Это изменение касается всех приложений независимо от целевого уровня API.
Некоторые приложения, например помощник по умолчанию для SMS и сопутствующие приложения для подключенных устройств, не задерживаются. Чтобы обеспечить бесперебойную работу, все приложения, которые считывают SMS для извлечения одноразовых кодов, должны перейти на SMS Retriever API или SMS User Consent API.
Безопасность
В Android 17 улучшена безопасность устройств и приложений.
План прекращения поддержки usesClearTraffic
В будущем мы планируем отказаться от элемента usesCleartextTraffic.
Если приложению необходимо устанавливать незашифрованные подключения (HTTP), перейдите на использование файла конфигурации сетевой безопасности. В нем можно указать, с какими доменами приложение должно устанавливать подключения с открытым текстом.
Обратите внимание, что файлы конфигурации сетевой безопасности поддерживаются только на API уровня 24 и выше. Если минимальный уровень API в вашем приложении ниже 24, выполните оба действия:
- Задайте для атрибута
usesCleartextTrafficзначениеtrue. - Как использовать файл конфигурации сети
Если минимальный уровень API вашего приложения – 24 или выше, вы можете использовать файл конфигурации сети и вам не нужно задавать usesCleartextTraffic.
Ограничить неявные разрешения URI
Сейчас, если приложение запускает намерение с URI, у которого есть действие ACTION_SEND, ACTION_SEND_MULTIPLE или ACTION_IMAGE_CAPTURE, система автоматически предоставляет целевому приложению разрешения на чтение и запись URI. Начиная с Android 18 система больше не будет автоматически предоставлять эти разрешения. Поэтому мы рекомендуем, чтобы приложения явно предоставляли соответствующие разрешения URI, а не полагались на то, что система предоставит их.
Чтобы обнаружить использование этих намерений в приложении, используйте StrictMode с detectImplicitUriPermissionGrant(). Это приведет к нарушению:
Kotlin
val policy = StrictMode.VmPolicy.Builder() .detectImplicitUriPermissionGrant() .penaltyLog() .build() StrictMode.setVmPolicy(policy)
Java
StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() .detectImplicitUriPermissionGrant() .penaltyLog() .build(); StrictMode.setVmPolicy(policy);
Вы также можете отслеживать зарегистрированные исключения, содержащие сообщение Please set the grant explicitly in the app, которое появляется, когда система неявно устанавливает разрешение. Вы можете отслеживать эти журналы с помощью следующей команды adb:
adb logcat | grep "Please set the grant explicitly in the app"
Чтобы явно предоставить необходимые разрешения, добавьте флаг FLAG_GRANT_READ_URI_PERMISSION к намерениям ACTION_SEND и ACTION_SEND_MULTIPLE:
Kotlin
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
Java
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Включите флаги FLAG_GRANT_READ_URI_PERMISSION и FLAG_GRANT_WRITE_URI_PERMISSION для намерений ACTION_IMAGE_CAPTURE:
Kotlin
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
Java
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Ограничения хранилища ключей для отдельных приложений
Не создавайте слишком много ключей в Android Keystore, поскольку это общий ресурс для всех приложений на устройстве. Начиная с Android 17, система ограничивает количество ключей, которыми может владеть приложение. Для несистемных приложений,предназначенных для Android 17 (уровень API 37) или более поздней версии, лимит составляет 50 000 ключей,а для всех остальных приложений – 200 000 ключей. Для системных приложений лимит составляет 200 000 ключей независимо от уровня API.
Если приложение попытается создать ключи сверх лимита, произойдет ошибка KeyStoreException. Строка сообщения об исключении содержит информацию о лимите ключей. Если приложение вызывает getNumericErrorCode() для исключения, возвращаемое значение зависит от целевого уровня API приложения:
- Приложения, предназначенные для Android 17 (уровень API 37) или более поздней версии:
getNumericErrorCode()возвращает новое значениеERROR_TOO_MANY_KEYS. - Все остальные приложения:
getNumericErrorCode()возвращаетERROR_INCORRECT_USAGE.
Блокировать трафик обратной связи между профилями
Начиная с Android 17, трафик обратной связи между профилями по умолчанию запрещен. Это не влияет на трафик обратной связи в одном профиле. Это изменение касается всех приложений, работающих на Android 17 и более поздних версиях, независимо от целевого уровня API.
Удобство для пользователей и системный интерфейс
В Android 17 внесены следующие изменения, призванные сделать работу с системой более единообразной и интуитивно понятной.
Восстановление видимости IME по умолчанию после поворота
Начиная с Android 17, если конфигурация устройства меняется (например, при повороте экрана) и это не обрабатывается приложением, предыдущая видимость IME не восстанавливается.
Если в приложении происходит изменение конфигурации, которое оно не обрабатывает, и после этого изменения клавиатура должна быть видна, вы должны явно запросить это. Это можно сделать одним из следующих способов:
- Для атрибута
android:windowSoftInputModeнеобходимо задать значениеstateAlwaysVisible. - Программно запросите экранную клавиатуру в методе
onCreate()объекта activity или добавьте методonConfigurationChanged().
Действия специалистов
В Android 17 внесены следующие изменения, которые влияют на то, как приложения взаимодействуют с устройствами ввода, такими как клавиатуры и сенсорные панели.
Сенсорные панели по умолчанию передают относительные события во время захвата указателя
Начиная с Android 17, если приложение запрашивает захват указателя с помощью View.requestPointerCapture(), а пользователь использует сенсорную панель, система распознает жесты перемещения указателя и прокрутки по касаниям пользователя и сообщает о них приложению так же, как о перемещениях указателя и колеса прокрутки от захваченной мыши. В большинстве случаев это избавляет от необходимости добавлять в приложения, поддерживающие захват мыши, специальную логику обработки для сенсорных панелей. Подробную информацию вы найдете в документации по View.POINTER_CAPTURE_MODE_RELATIVE.
Ранее система не пыталась распознавать жесты на сенсорной панели, а передавала приложению необработанные абсолютные координаты пальцев в формате, аналогичном касаниям сенсорного экрана. Если приложению по-прежнему нужны абсолютные данные, оно должно вызвать новый метод View.requestPointerCapture(int) с View.POINTER_CAPTURE_MODE_ABSOLUTE.
Мультимедиа
В Android 17 внесены следующие изменения в работу с медиаконтентом.
Усиление защиты аудио в фоновом режиме
Начиная с Android 17, аудиофреймворк накладывает ограничения на фоновые аудиовзаимодействия, включая воспроизведение аудио, запросы на фокусировку звука и API изменения громкости, чтобы гарантировать, что эти изменения запускаются пользователем намеренно.
Если приложение пытается вызвать API аудио, когда оно находится в недопустимом жизненном цикле, API воспроизведения аудио и изменения громкости не срабатывают без выдачи исключения или сообщения об ошибке. API аудиофокуса возвращает код ошибки AUDIOFOCUS_REQUEST_FAILED.
Дополнительную информацию, в том числе о стратегиях устранения уязвимостей, можно найти в статье Усиление защиты фонового аудио.
Функции связи
В Android 17 внесены следующие изменения, улучшающие подключение устройств.
Автоматическое повторное подключение при потере связи по Bluetooth.
В Android 17 появилось автономное повторное подключение – улучшение на уровне системы, предназначенное для автоматического устранения потери связи по Bluetooth.
Раньше, если связь терялась, пользователям приходилось вручную переходить в настройки, чтобы отключить периферийное устройство, а затем снова подключить его. Эта функция основана на улучшении безопасности в Android 16. Она позволяет системе восстанавливать связь в фоновом режиме, чтобы пользователям не приходилось вручную переходить в настройки, отключать периферийные устройства и снова подключать их.
Хотя в большинстве приложений не потребуется менять код, разработчикам следует учитывать следующие изменения в поведении стека Bluetooth:
- Новый контекст подключения. В
ACTION_PAIRING_REQUESTтеперь есть дополнительный параметрEXTRA_PAIRING_CONTEXT, который позволяет приложениям различать стандартный запрос на подключение и попытку повторного подключения, инициированную автономной системой. - Условное обновление ключей. Существующие ключи безопасности будут заменены, только если повторное подключение выполнено успешно и новое подключение соответствует уровню безопасности предыдущего или превосходит его.
- Изменено время отправки намерения. Намерение
ACTION_KEY_MISSINGтеперь транслируется, только если попытка автономного повторного подключения не удалась. Это позволяет избежать ненужной обработки ошибок в приложении, если система успешно восстанавливает связь в фоновом режиме. - Уведомление пользователя. Система управляет повторным подключением с помощью новых уведомлений и диалоговых окон в интерфейсе. Пользователям будет предложено подтвердить попытку повторного подключения, чтобы они знали о повторном подключении.
Производители периферийных устройств и разработчики сопутствующих приложений должны убедиться, что аппаратное обеспечение и приложение корректно обрабатывают переходы между связями. Чтобы проверить это поведение, смоделируйте потерю связи с удаленным устройством одним из следующих способов:
- Вручную удалите информацию о связи с периферийного устройства.
- Отключите устройство вручную в разделе "Настройки > Подключенные устройства".