Платформа 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 Display для получения границ приложения, 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
Java
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
Java
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 ) к выходному изображению камеры применяется дополнительное вращение для компенсации ориентации датчика камеры, а выходное изображение обрезается в соответствии с соотношением сторон предварительного просмотра камеры в приложении. Обрезка и дополнительное вращение обеспечивают правильное отображение предварительного просмотра камеры независимо от ориентации устройства и его сложенного или разложенного состояния.
Задержка пользовательского интерфейса для уведомлений от служб переднего плана
Для обеспечения более эффективной работы кратковременных служб переднего плана устройства под управлением Android 12 и выше могут задерживать отображение уведомлений служб переднего плана на 10 секунд, за некоторыми исключениями . Это изменение дает кратковременным задачам возможность завершиться до появления соответствующих уведомлений.
Производительность
Ограниченный резервный сегмент приложений
В Android 11 (уровень API 30) был представлен ограниченный сегмент как сегмент ожидания приложения. Начиная с 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 выдает ошибку раньше.Инициализация шифров Галуа/Счетчика (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 , обновите свою реализацию, чтобы вместо завершения Activity вызывался метод super.onBackPressed() . Вызов super.onBackPressed() перемещает Activity и её задачу в фоновый режим, когда это необходимо, и обеспечивает более согласованную навигацию для пользователей в разных приложениях.
Также следует отметить, что в целом мы рекомендуем использовать API AndroidX Activity для предоставления пользовательской навигации «Назад» , а не переопределять onBackPressed() . API AndroidX Activity автоматически используют соответствующее системное поведение, если нет компонентов, перехватывающих системное нажатие кнопки «Назад».
Графика и изображения
Улучшено переключение частоты обновления.
В 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)
Java
// 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);
Подключение
Обновления Passpoint
В Android 12 добавлены следующие API:
- Функция
isPasspointTermsAndConditionsSupported()позволяет заменить небезопасные порталы авторизации , использующие открытые сети, на защищенную сеть Passpoint. При необходимости принятия условий авторизации пользователю отображается уведомление. Приложения, предлагающие сети Passpoint с условиями авторизации, должны сначала вызвать этот API, чтобы убедиться, что устройство поддерживает эту функцию. Если устройство не поддерживает эту функцию, оно не сможет подключиться к этой сети, и будет предложена альтернативная или устаревшая сеть. isDecoratedIdentitySupported(): При аутентификации в сетях с префиксным декорированием, декорированный префикс идентификации позволяет сетевым операторам обновлять идентификатор доступа к сети (NAI) для выполнения явной маршрутизации через несколько прокси-серверов внутри сети AAA (подробнее см. RFC 7542 ).В Android 12 эта функция реализована в соответствии со спецификацией WBA для расширений PPS-MO . Приложения, предлагающие сети Passpoint, требующие помеченного идентификатора, должны сначала вызвать этот API, чтобы убедиться, что устройство поддерживает эту возможность. Если устройство не поддерживает эту возможность, идентификатор не будет помечен, и аутентификация в сети может завершиться неудачей.
Для создания предложения по точке доступа приложения должны использовать классы PasspointConfiguration , Credential и HomeSp . Эти классы описывают профиль точки доступа, определенный в спецификации 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» .