Платформа Android 12 включает изменения поведения, которые могут повлиять на ваше приложение. Следующие изменения поведения применяются ко всем приложениям , когда они работают на Android 12, независимо от targetSdkVersion
. Вам следует протестировать свое приложение, а затем изменить его по мере необходимости для поддержки этих функций должным образом, где это применимо.
Обязательно ознакомьтесь со списком изменений поведения, которые затрагивают только приложения, предназначенные для Android 12 .
Пользовательский опыт
Эффект растягивания прокрутки
На устройствах под управлением Android 12 и выше визуальное поведение событий прокрутки изменяется.
На Android 11 и ниже событие прокрутки вызывает свечение визуальных элементов; на Android 12 и выше визуальные элементы растягиваются и отскакивают назад при событии перетаскивания, а также отскакивают и отскакивают назад при событии отбрасывания.
Более подробную информацию см. в руководстве по анимации жестов прокрутки .
Заставки приложений
Если вы ранее реализовали пользовательский экран-заставку в Android 11 или более ранней версии, вам необходимо перенести свое приложение на API SplashScreen
, чтобы обеспечить его корректное отображение, начиная с Android 12. Если не выполнить миграцию, запуск приложения будет ухудшен или возникнут непреднамеренные проблемы.
Инструкции см. в разделе Перенос существующей реализации заставки на Android 12 .
Кроме того, начиная с Android 12, система всегда применяет новый системный экран-заставку Android по умолчанию при холодном и теплом запуске для всех приложений. По умолчанию этот системный экран-заставка по умолчанию создается с использованием элемента значка запуска вашего приложения и windowBackground
вашей темы (если он одноцветный).
Более подробную информацию см. в руководстве разработчика заставок .
Разрешение веб-намерений
Начиная с Android 12 (уровень API 31), общее веб-намерение разрешается в активность в вашем приложении, только если ваше приложение одобрено для определенного домена, содержащегося в этом веб-намерении. Если ваше приложение не одобрено для домена, веб-намерение разрешается в приложение браузера пользователя по умолчанию.
Приложения могут получить это одобрение, выполнив одно из следующих действий:
Проверьте домен с помощью ссылок на приложения Android .
В приложениях, ориентированных на Android 12 или выше, система изменяет способ автоматической проверки ссылок Android App Links вашего приложения. В фильтрах намерений вашего приложения проверьте, что вы включаете категорию
BROWSABLE
и поддерживаете схемуhttps
.На устройствах с Android 12 и выше вы можете вручную проверить ссылки приложений Android, чтобы узнать, как обновленная логика влияет на ваше приложение.
Попросите пользователя связать ваше приложение с доменом в настройках системы.
Если ваше приложение вызывает веб-намерения, рассмотрите возможность добавления подсказки или диалогового окна, предлагающего пользователю подтвердить действие.
Улучшения режима погружения для навигации с помощью жестов
Android 12 объединяет существующее поведение, чтобы упростить для пользователей выполнение команд навигации жестами в режиме погружения . Кроме того, Android 12 обеспечивает поведение обратной совместимости для режима закрепления погружения .
Display#getRealSize и getRealMetrics: устаревание и ограничения
Устройства Android доступны во многих различных форм-факторах, таких как большие экраны, планшеты и складные устройства. Чтобы отобразить контент соответствующим образом для каждого устройства, вашему приложению необходимо определить размер экрана или дисплея. Со временем Android предоставил различные API для получения этой информации. В Android 11 мы представили API WindowMetrics
и объявили устаревшими следующие методы:
В Android 12 мы по-прежнему рекомендуем использовать WindowMetrics
и прекращаем поддержку следующих методов:
Чтобы смягчить поведение приложений, использующих API отображения для получения границ приложения, Android 12 ограничивает значения, возвращаемые API для приложений, которые не полностью изменяемы по размеру. Это может повлиять на приложения, которые используют эту информацию с MediaProjection
.
Приложения должны использовать API WindowMetrics
для запроса границ своего окна и Configuration.densityDpi
для запроса текущей плотности.
Для более широкой совместимости со старыми версиями Android можно использовать библиотеку Jetpack WindowManager
, которая включает класс WindowMetrics
, поддерживающий Android 4.0 (API уровня 14) и выше.
Примеры использования WindowMetrics
Во-первых, убедитесь, что действия вашего приложения полностью масштабируемы .
Действие должно полагаться на WindowMetrics
из контекста действия для любой работы, связанной с пользовательским интерфейсом, в частности, WindowManager.getCurrentWindowMetrics()
или WindowMetricsCalculator.computeCurrentWindowMetrics()
из Jetpack.
Если ваше приложение создает MediaProjection
, границы должны иметь правильный размер, поскольку проекция захватывает раздел дисплея, в котором запущено приложение проектора.
Если приложение полностью масштабируемо, контекст активности возвращает правильные границы, например:
Котлин
val projectionMetrics: WindowMetrics = activityContext .getSystemService(WindowManager::class.java).maximumWindowMetrics
Ява
WindowMetrics projectionMetrics = activityContext .getSystemService(WindowManager.class).getMaximumWindowMetrics();
Если приложение не поддерживает полное изменение размера, оно должно выполнить запрос из экземпляра WindowContext
и получить WindowMetrics
границ активности с помощью WindowManager.getMaximumWindowMetrics()
или метода Jetpack WindowMetricsCalculator.computeMaximumWindowMetrics()
.
Котлин
val windowContext = context.createWindowContext(mContext.display!!, WindowManager.LayoutParams.TYPE_APPLICATION, null) val projectionMetrics = windowContext.getSystemService(WindowManager::class.java) .maximumWindowMetrics
Ява
Context windowContext = context.createWindowContext(mContext.getDisplay(), WindowManager.LayoutParams.TYPE_APPLICATION, null); WindowMetrics projectionMetrics = windowContext.getSystemService(WindowManager.class) .getMaximumWindowMetrics();
Все приложения в многооконном режиме
В Android 12 многооконный режим стал стандартным поведением.
На больших экранах (sw >= 600dp) платформа поддерживает все приложения в многооконном режиме независимо от конфигурации приложения. Если resizeableActivity="false"
, приложение переводится в режим совместимости, когда это необходимо для размещения размеров дисплея.
На маленьких экранах (sw < 600dp) система проверяет minWidth
и minHeight
активности, чтобы определить, может ли активность работать в многооконном режиме. Если resizeableActivity="false"
, приложение не может работать в многооконном режиме независимо от минимальной ширины и высоты.
Для получения дополнительной информации см. Поддержка многооконного режима .
Предварительный просмотр камеры на больших экранах
Приложения камеры обычно предполагают фиксированную связь между ориентацией устройства и соотношением сторон предварительного просмотра камеры. Но большие форм-факторы экрана, такие как складные устройства, и режимы отображения, такие как многооконный и многодисплейный, бросают вызов этому предположению.
На Android 12 приложения камеры, которые запрашивают определенную ориентацию экрана и не могут быть изменены по размеру ( resizeableActivity="false"
), автоматически переходят в режим портретной вставки, который обеспечивает правильную ориентацию и соотношение сторон предварительного просмотра камеры. На складных устройствах и других устройствах, которые имеют уровень абстракции оборудования камеры ( HAL ), к выходу камеры применяется дополнительный поворот для компенсации ориентации сенсора камеры, а выход камеры обрезается в соответствии с соотношением сторон предварительного просмотра камеры приложения. Обрезка и дополнительный поворот обеспечивают правильное представление предварительного просмотра камеры независимо от ориентации устройства и сложенного или развернутого состояния устройства.
Задержка UX для уведомлений служб переднего плана
Чтобы обеспечить оптимизированный опыт для кратковременных служб переднего плана , устройства под управлением Android 12 или выше могут задерживать отображение уведомлений служб переднего плана на 10 секунд, за некоторыми исключениями . Это изменение дает кратковременным задачам возможность завершиться до появления их уведомлений.
Производительность
Ограниченный резервный контейнер приложений
Android 11 (API уровня 30) представил ограниченный контейнер как App Standby Bucket. Начиная с Android 12, этот контейнер активен по умолчанию. Ограниченный контейнер имеет самый низкий приоритет (и самые высокие ограничения) из всех контейнеров. Контейнеры в порядке приоритета от высокого к низкому:
- Активно: приложение используется в данный момент или использовалось совсем недавно.
- Рабочий набор: Приложение используется регулярно.
- Часто: приложение используется часто, но не каждый день.
- Редко: приложение используется нечасто.
- Ограничено: приложение потребляет много системных ресурсов или может вести себя нежелательно.
Система учитывает поведение вашего приложения, а также шаблоны использования, чтобы решить, следует ли поместить ваше приложение в ограниченную корзину.
Ваше приложение с меньшей вероятностью будет помещено в ограниченную корзину, если оно более ответственно использует системные ресурсы. Кроме того, система помещает ваше приложение в менее ограничивающую корзину, если пользователь напрямую взаимодействует с вашим приложением.
Проверьте, находится ли ваше приложение в ограниченном сегменте
Чтобы проверить, поместила ли система ваше приложение в ограниченную корзину, вызовите getAppStandbyBucket()
. Если возвращаемое значение этого метода равно STANDBY_BUCKET_RESTRICTED
, то ваше приложение находится в ограниченной корзине.
Тестирование поведения ограниченного ведра
Чтобы проверить, как ведет себя ваше приложение, когда система помещает его в ограниченный контейнер, вы можете вручную переместить свое приложение в этот контейнер. Для этого выполните следующую команду в окне терминала:
adb shell am set-standby-bucket PACKAGE_NAME restricted
Расположение на переднем плане и экономия заряда батареи
Начиная с Android 12, приоритетное местоположение (в том числе из приоритетной службы) может продолжать предоставляться при активной функции экономии заряда батареи, даже если экран выключен.
Ранее режим экономии заряда батареи останавливал обновления местоположения, когда экран был выключен. Это изменение обеспечивает более длительный срок службы батареи для пользователей и означает, что разработчики могут воздержаться от просьб пользователей отключить экономию заряда батареи, чтобы обеспечить доставку данных о местоположении.
Приложения, запрашивающие местоположение через службу переднего плана, должны выполнить следующие шаги:
- Вызовите
getLocationPowerSaverMode()
чтобы проверить, как ведут себя функции определения местоположения устройства при активном режиме экономии заряда батареи. - Если возвращается значение
LOCATION_MODE_FOREGROUND_ONLY
, ваше приложение продолжит получать обновления местоположения, находясь на переднем плане или выполняя службу на переднем плане, при включенном режиме экономии заряда батареи и выключенном экране.
Безопасность и конфиденциальность
Приблизительное местоположение
На устройствах под управлением Android 12 или более поздней версии пользователи могут запросить у вашего приложения доступ только к приблизительной информации о местоположении .
Если ваше приложение запрашивает разрешение ACCESS_FINE_LOCATION
во время выполнения, вам также следует запросить разрешение ACCESS_COARSE_LOCATION
для обработки случая, когда пользователь предоставляет вашему приложению доступ к приблизительному местоположению. Вам следует включить оба разрешения в один запрос во время выполнения .
Диалоговое окно системных разрешений включает в себя следующие параметры для пользователя, как показано на рисунке 1:
- Точность : обеспечивает доступ к точной информации о местоположении.
- Приблизительное : предоставляет доступ только к приблизительной информации о местоположении.
Переключатели микрофона и камеры
Поддерживаемые устройства под управлением Android 12 или выше позволяют пользователям включать и отключать доступ к камере и микрофону для всех приложений на устройстве, нажав одну опцию переключения. Пользователи могут получить доступ к переключаемым опциям из быстрых настроек , как показано на рисунке 1, или из экрана конфиденциальности в системных настройках.
Узнайте больше об этих переключателях и о том, как проверить, соответствует ли ваше приложение лучшим практикам в отношении разрешений CAMERA
и RECORD_AUDIO
.
Индикаторы микрофона и камеры
На устройствах под управлением Android 12 или более поздней версии, когда приложение получает доступ к микрофону или камере, в строке состояния появляется значок.
Узнайте больше об этих индикаторах и о том, как проверить, соответствует ли ваше приложение передовым практикам в отношении разрешений CAMERA
и RECORD_AUDIO
.
Видимость пакета разрешений
На устройствах под управлением Android 12 или более поздней версии приложения, ориентированные на Android 11 (уровень API 30) или более поздней версии и вызывающие один из следующих методов, получают отфильтрованный набор результатов на основе видимости пакета приложения в других приложениях:
Реализация BouncyCastle удалена
Android 12 удаляет многие реализации BouncyCastle криптографических алгоритмов, которые ранее были объявлены устаревшими, включая все алгоритмы AES. Вместо этого система использует реализации Conscrypt этих алгоритмов.
Это изменение повлияет на ваше приложение, если выполняется хотя бы одно из следующих условий:
- Ваше приложение использует 512-битные размеры ключей. Conscrypt не поддерживает этот размер ключа. При необходимости обновите криптографическую логику вашего приложения, чтобы использовать другие размеры ключей.
Ваше приложение использует недопустимые размеры ключей с
KeyGenerator
. РеализацияKeyGenerator
в Conscrypt выполняет дополнительную проверку параметров ключей по сравнению с BouncyCastle. Например, Conscrypt не позволяет вашему приложению генерировать 64-битный ключ AES, поскольку AES поддерживает только 128-, 192- и 256-битные ключи.BouncyCastle позволяет генерировать ключи недопустимых размеров, но позже дает сбой, если эти ключи используются с
Cipher
. Conscrypt дает сбой раньше.Вы инициализируете свои шифры Galois/Counter Mode (GCM) с использованием размера, отличного от 12 байт. Реализация
GcmParameterSpec
в Conscrypt требует инициализации 12 байт, что рекомендует NIST.
Уведомления о доступе к буферу обмена
На Android 12 и выше, когда приложение впервые вызывает getPrimaryClip()
для доступа к данным клипа из другого приложения , всплывающее сообщение уведомляет пользователя об этом доступе к буферу обмена.
Текст внутри всплывающего сообщения имеет следующий формат: APP pasted from your clipboard.
Информация о тексте в описании клипа
На Android 12 и выше getPrimaryClipDescription()
может обнаружить следующие данные:
- Стилизованный текст с использованием
isStyledText()
. - Различные классификации текста, например URL-адресов, с использованием
getConfidenceScore()
.
Приложения не могут закрывать системные диалоги
Чтобы улучшить контроль пользователя при взаимодействии с приложениями и системой, действие намерения ACTION_CLOSE_SYSTEM_DIALOGS
устарело, начиная с Android 12. За исключением нескольких особых случаев , когда ваше приложение пытается вызвать намерение , содержащее это действие, система выполняет одно из следующих действий в зависимости от целевой версии SDK вашего приложения:
- Если ваше приложение предназначено для Android 12 или выше, возникает
SecurityException
. Если ваше приложение предназначено для Android 11 (уровень API 30) или ниже, намерение не выполняется, а в Logcat появляется следующее сообщение:
E ActivityTaskManager Permission Denial: \ android.intent.action.CLOSE_SYSTEM_DIALOGS broadcast from \ com.package.name requires android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, \ dropping broadcast.
Исключения
В следующих случаях приложение по-прежнему может закрывать системные диалоговые окна на Android 12 или выше:
- Ваше приложение выполняет инструментальный тест .
Ваше приложение предназначено для Android 11 или более ранних версий и отображает окно поверх панели уведомлений .
Ваше приложение предназначено для Android 11 или ниже. Кроме того, пользователь взаимодействовал с уведомлением, возможно, используя кнопки действий уведомления, и ваше приложение обрабатывает службу или вещательный приемник в ответ на это действие пользователя.
Ваше приложение предназначено для Android 11 или ниже и имеет активную службу специальных возможностей . Если ваше приложение предназначено для Android 12 и хочет закрыть панель уведомлений, используйте вместо этого действие специальных возможностей
GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE
.
Недоверенные события касания блокируются
Для сохранения безопасности системы и хорошего пользовательского опыта Android 12 не позволяет приложениям использовать сенсорные события , когда наложение закрывает приложение небезопасным образом. Другими словами, система блокирует касания, которые проходят через определенные окна, за некоторыми исключениями .
Затронутые приложения
Это изменение влияет на приложения, которые позволяют касаниям проходить через их окна, например, с помощью флага FLAG_NOT_TOUCHABLE
. Несколько примеров включают, но не ограничиваются, следующим:
- Наложения, требующие разрешения
SYSTEM_ALERT_WINDOW
, например окна, использующиеTYPE_APPLICATION_OVERLAY
и флагFLAG_NOT_TOUCHABLE
. - Окна активности, использующие флаг
FLAG_NOT_TOUCHABLE
.
Исключения
В следующих случаях допускаются «сквозные» касания:
- Взаимодействия в вашем приложении. Ваше приложение показывает наложение, и наложение появляется только тогда, когда пользователь взаимодействует с вашим приложением.
Доверенные окна. Эти окна включают (но не ограничиваются) следующее:
Полностью прозрачные окна. Свойство
alpha
равно 0.0 для окна.Достаточно полупрозрачные окна системных оповещений. Система считает набор окон системных оповещений достаточно полупрозрачным, если их общая непрозрачность меньше или равна максимальной непрозрачности затенения для касаний в системе. В Android 12 эта максимальная непрозрачность по умолчанию составляет 0,8.
Определите, когда несанкционированное касание заблокировано
Если сенсорное действие блокируется системой, Logcat регистрирует следующее сообщение:
Untrusted touch due to occlusion by PACKAGE_NAME
Проверьте изменение
Недоверенные касания по умолчанию блокируются на устройствах под управлением Android 12 или выше. Чтобы разрешить недоверенные касания, выполните следующую команду ADB в окне терминала:
# A specific app adb shell am compat disable BLOCK_UNTRUSTED_TOUCHES com.example.app # All apps # If you'd still like to see a Logcat message warning when a touch would be # blocked, use 1 instead of 0. adb shell settings put global block_untrusted_touches 0
Чтобы вернуть поведение по умолчанию (недоверенные касания блокируются), выполните следующую команду:
# A specific app adb shell am compat reset BLOCK_UNTRUSTED_TOUCHES com.example.app # All apps adb shell settings put global block_untrusted_touches 2
Жизненный цикл деятельности
Действия лаунчера root больше не завершаются при нажатии кнопки «Назад»
Android 12 изменяет обработку по умолчанию системного нажатия «Назад» для действий запуска, которые являются корнем их задач. В предыдущих версиях система завершала эти действия при нажатии «Назад». В Android 12 система теперь перемещает действие и его задачу в фоновый режим вместо завершения действия. Новое поведение соответствует текущему поведению при выходе из приложения с помощью кнопки «Домой» или жеста.
Для большинства приложений это изменение означает, что пользователи, которые используют кнопку «Назад» для выхода из приложения, смогут быстрее возобновить работу приложения из «теплого» состояния , вместо того чтобы полностью перезапускать приложение из «холодного» состояния .
Мы рекомендуем протестировать ваши приложения с этим изменением. Если ваше приложение в настоящее время переопределяет onBackPressed()
для обработки навигации «Назад» и завершения Activity
, обновите свою реализацию, чтобы вызвать super.onBackPressed()
вместо завершения. Вызов super.onBackPressed()
перемещает activity и его задачу на задний план, когда это уместно, и обеспечивает более последовательный опыт навигации для пользователей в разных приложениях.
Также обратите внимание, что в целом мы рекомендуем использовать API AndroidX Activity для предоставления пользовательской навигации назад , а не переопределять onBackPressed()
. API AndroidX Activity автоматически переходят на соответствующее системное поведение, если нет компонентов, перехватывающих системное нажатие Back.
Графика и изображения
Улучшенное переключение частоты обновления
В Android 12 изменение частоты обновления с помощью setFrameRate()
может происходить независимо от того, поддерживает ли дисплей плавный переход к новой частоте обновления; плавный переход — это переход, который не имеет никаких визуальных прерываний, таких как черный экран на секунду или две. Ранее, если дисплей не поддерживал плавный переход, он обычно продолжал использовать ту же частоту обновления после вызова setFrameRate()
. Вы можете заранее определить, будет ли переход к новому обновлению плавным, вызвав getAlternativeRefreshRates()
. Обычно обратный вызов onDisplayChanged()
вызывается после завершения переключения частоты обновления, но для некоторых дисплеев с внешним подключением он вызывается во время неплавного перехода.
Вот пример того, как это можно реализовать:
Котлин
// Determine whether the transition will be seamless. // Non-seamless transitions may cause a 1-2 second black screen. val refreshRates = this.display?.mode?.alternativeRefreshRates val willBeSeamless = Arrays.asList<FloatArray>(refreshRates).contains(newRefreshRate) // Set the frame rate even if the transition will not be seamless. surface.setFrameRate(newRefreshRate, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS)
Ява
// Determine whether the transition will be seamless. // Non-seamless transitions may cause a 1-2 second black screen. Display display = context.getDisplay(); // API 30+ Display.Mode mode = display.getMode(); float[] refreshRates = mode.getAlternativeRefreshRates(); boolean willBeSeamless = Arrays.asList(refreshRates).contains(newRefreshRate); // Set the frame rate even if the transition will not be seamless. surface.setFrameRate(newRefreshRate, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS);
Связность
Обновления пропускных пунктов
В Android 12 добавлены следующие API:
-
isPasspointTermsAndConditionsSupported()
: Условия и положения — это функция Passpoint , которая позволяет сетевым развертываниям заменять небезопасные порталы захвата, которые используют открытые сети, на безопасную сеть Passpoint. Уведомление отображается пользователю, когда требуется принять условия и положения. Приложения, предлагающие сети Passpoint, которые ограничены условиями и положениями, должны сначала вызвать этот API, чтобы убедиться, что устройство поддерживает эту возможность. Если устройство не поддерживает эту возможность, оно не сможет подключиться к этой сети, и должна быть предложена альтернативная или устаревшая сеть. isDecoratedIdentitySupported()
: при аутентификации в сетях с декорированием префикса декорированный префикс идентификации позволяет сетевым операторам обновлять идентификатор доступа к сети (NAI) для выполнения явной маршрутизации через несколько прокси-серверов внутри сети AAA (подробнее об этом см. в RFC 7542 ).Android 12 реализует эту функцию для соответствия спецификации WBA для расширений PPS-MO . Приложения, предлагающие сети Passpoint, требующие декорированную идентификацию, должны сначала вызвать этот API, чтобы убедиться, что устройство поддерживает эту возможность. Если устройство не поддерживает эту возможность, идентификация не будет декорирована, и аутентификация в сети может не пройти.
Чтобы создать предложение Passpoint, приложения должны использовать классы PasspointConfiguration
, Credential
и HomeSp
. Эти классы описывают профиль Passpoint, который определен в спецификации Wi-Fi Alliance Passpoint .
Для получения дополнительной информации см. API предложений Wi-Fi для подключения к Интернету .
Обновлены ограничения интерфейса, не входящего в SDK
Android 12 включает обновленные списки ограниченных интерфейсов не-SDK, основанные на сотрудничестве с разработчиками Android и последнем внутреннем тестировании. По возможности мы обеспечиваем доступность общедоступных альтернатив, прежде чем ограничивать интерфейсы не-SDK.
Если ваше приложение не ориентировано на Android 12, некоторые из этих изменений могут не сразу вас затронуть. Однако, хотя в настоящее время вы можете использовать некоторые интерфейсы, не относящиеся к SDK ( в зависимости от целевого уровня API вашего приложения ), использование любого метода или поля, не относящегося к SDK, всегда несет высокий риск поломки вашего приложения.
Если вы не уверены, использует ли ваше приложение интерфейсы, отличные от SDK, вы можете протестировать его , чтобы узнать. Если ваше приложение использует интерфейсы, отличные от SDK, вам следует начать планировать миграцию на альтернативы SDK. Тем не менее, мы понимаем, что некоторые приложения имеют допустимые варианты использования интерфейсов, отличных от SDK. Если вы не можете найти альтернативу использованию интерфейса, отличного от SDK, для функции в вашем приложении, вам следует запросить новый публичный API .
Чтобы узнать больше об изменениях в этой версии Android, см. Обновления ограничений интерфейсов, не относящихся к SDK, в Android 12. Чтобы узнать больше об интерфейсах, не относящихся к SDK, см. Ограничения интерфейсов, не относящихся к SDK .