Все новинки Android 12. Обзор для разработчиков

Привет. Меня зовут Кирилл Розов и вы если вы интересуетесь разработкой под Android, то скорее всего слышали о Telegram канале «Android Broadcast», с ежедневными новостями для Android разработчиков, и одноимённом YouTube канале. Этот пост является текстовой расшифровкой нового видео на канале

Прошла конференция Google I/O и мы узнали абсолютно всё про новую версию Android, а также всё это можно попробовать в Beta 1, которую на Pixel можно установить по воздуху, а также ряд других производителей позволяют установить GSI образ.

Основной упор в релизе был сделан на усиление безопасности ОС и приватности данных и редизайн системы. Очень хорошо поработали с поддержкой новых современных стандартов медиа, причём минимизировали объем боли которые будут испытывать флагманские устройства из-за старых или бюджетных смартфонов. App Widgets воскресили и сделали улучшения, которые просили еще с первой версии Android.

Дизайн

Новый дизайн Material You

Google представила обновлённую версию Material Design, которая акцентирует внимание на персонализации цветовой палитры. Например, в Pixel устройствах цвета будут определяться на основе фоновой картинки. Полноценно попробовать Material You получится во второй Beta версии Android 12

Самый главный вопрос: «как вендоры будут адаптировать Material You в своих прошивках?» Есть вероятность что эта концепция цветов так и останется в чистом Android, а вендоры и сторонние приложения будут игнорировать дизайн и использовать свои собственные наработки. Вся палитра цветов в Material была основана на цветах бренда приложения, а сейчас должна задаваться пользователем. Хотя многое зависит как дизайнеры интерфейса приложений адаптируют новый дизайн. Пишите в комментариях как вам новый визуальный стиль Google

Стандартный Splash Screen для всех приложений

ПримПрим

Splash Screen — довольно популярная практика в Android приложениях чтобы скрыть долгую инициализацию. Теперь в Android появляется стандартный Splash Screen, который будет анимировать открытия приложения из иконки в launcher.

SplashScreen может быть кастомизирован для вашего бренда. Можно задать фон, анимированную иконку и другие параметры. Отключить новый Splash Screen нельзя, поэтому у всех кого есть своя вариация такого экрана — обратите внимание.

@color/...
@drawable/...
@color/...
@drawable/...

Обновление эффектов UI

Ripple эффект

1294ed92929bd8dc1acd55e367a1e509.gif

Обновление дизайна затронула многие аспекты UI системы, даже Ripple эффект обновился. Теперь в него добавили эффект аля «белый шум» по краям. Мне нравился старый одноцветный Ripple и новый выглядит странным и неестественным

Overscroll

3a7b2e0f439f1f60fb62bb296121e9c8.gif

Новый эффект при достижении граница списке стал доступен в Android 12 для нативных (Android View) системы. Тем кто использует iOS новый эффект overscroll будет очень знаком.

RenderEffect API

435ec6124abacce8e17ba82d203292a3.png

Новое API, которое позволит делать размытия, цветовые фильтры и другие графические эффекты намного проще и эффективнее. Теперь добиться размытия окна как в iOS можно всего лишь одной строчкой API

// Задание эффекта для любой View
view.setRenderEffect(RenderEffect.createBlurEffect(radiusX, radiusY, SHADER_TILE_MODE))
// Размытие фона Window из кода
Window.setBackgroundBlurRadius(radius: Int)
// Задание размиытие фона в теме

Виджеты

e5c6836cad11c8506417715851589adc.png

В Android 12 значительно переработали API виджетов рабочего стола. Мне кажется, что появление этого функционала в iOS 14 подстегнуло Google обратить внимание на жалобы разработчиков на это API еще с самой первой версии Android. Что теперь появилось:

  • Закруглённые края у фона всех виджетов на Android 12+

  • Виджеты могут использовать динамические цвета из темы, которые являются нововведением Material You

  • Начальная настройка виджета может быть необязательной и этот этап может пропускаться

  • Добавлена поддержка CheckBox, Switch и RadioButton. Обрадоваться могу разные Todo списки и приложения, где есть настройки через тумблеры


  • На превью виджета теперь можно ставить не только статическую картинку, но и верстать UI в XML и добавлять описание

  • Анимации при открытии приложения по клику на виджет. Фон виджета будет трансформироваться в фон окна открываемой Activity

  • Упрощение API для работы со списками в виджетах

  • Большое руководство по обратной совместимости для виджетов до Android 12 и после

Помимо прочего нам обещают библиотеку для написания виджетов в DSL стиле подобно Compose, с поддержкой старых версий Android. Это будет специальное DSL, которое конвертируется в иерархию View, но уже приятно что Compose стиль будет идти и в существующий функционал системы.

Rounded Corner API

Rounded Corner API позволит получать информацию о дисплеях с закруглениями и размещать свой контент безопасно, чтобы он не обрезался.

Пример, который приводит Google, для смещения контента на основе полученной информации о закруглениях не выглядит маленьким, но зато теперь хотя бы есть возможность.

// Get the top-right rounded corner from WindowInsets.
final WindowInsets insets = getRootWindowInsets();
final RoundedCorner topRight = insets.getRoundedCorner(POSITION_TOP_RIGHT);
if (topRight == null) {
   return;
}

// Get the location of the close button in window coordinates.
int [] location = new int[2];
closeButton.getLocationInWindow(location);
final int buttonRightInWindow = location[0] + closeButton.getWidth();
final int buttonTopInWindow = location[1];

// Find the point on the quarter circle with a 45 degree angle.
final int offset = (int) (topRight.getRadius() * Math.sin(Math.toRadians(45)));
final int topBoundary = topRight.getCenter().y - offset;
final int rightBoundary = topRight.getCenter().x + offset;

// Check whether the close button exceeds the boundary.
if (buttonRightInWindow < rightBoundary && buttonTopInWindow > topBoundary) {
   return;
}

// Set the margin to avoid truncating.
int [] parentLocation = new int[2];
getLocationInWindow(parentLocation);
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) closeButton.getLayoutParams();
lp.rightMargin = Math.max(buttonRightInWindow - rightBoundary, 0);
lp.topMargin = Math.max(topBoundary - buttonTopInWindow, 0);
closeButton.setLayoutParams(lp);

Rich Content Insertion

Шаринг контента между разными приложениями — важная возможность любой системы. Google упрощает жизнь разработчиков и теперь вместо трёх отдельных API вставки содержимого через drag-&-drop, изображений из клавиатуры и буфера обмена мы получили один — Rich Content Insertion. Также compat API OnReceiveContentListener уже добавлено в Jetpack Core 1.5.0, который вышел в Stable.

f287e4cf20b6abe23479ab3bb0f4bbc1.jpg

Уведомления

Какое обновления Android без переработки уведомлений. Для начала снова поменялся их шаблон и появилось несколько новых возможностей:

  • В MessagingStyle и BigPictureStyle можно добавлять анимированные картинки

  • Действия на уведомлениях во время показа их на экране блокировки можно потребовать обязательной авторизации пользователя перед отправкой Intent

  • Новый стиль уведомлений для звонков — CallStyle, который позволяет создать разные стили для входящего, исходящего и текущего звонка. Также можно задавать важность для звонков

  • Зона в уведомлении, выделяемая для Custom View, теперь становится меньше.

    16225d6ce56e12122e7b31cd438a97b0.pngad570b177ef828f222d71574fbbe0309.png

Запрет «трамплинов» в уведомлениях

Под трамплином понимается случай когда нажатие на уведомление приводит к запуску Activity, но делается это не напрямую. Например, вы сначала запускаете BroadcastReceiver, а из него уже стартует Activity. Для улучшения производительности и UX теперь так делать запрещено. Хотите запустить Activity из уведомления — делайте это напрямую. В противном случае ничего происходит не будет, а в логи упадёт ошибка

Indirect notification activity start (trampoline) from PACKAGE_NAME, \
this should be avoided for performance reasons.

Медиа

Поддержка AVIF

Поддержка изображений формата изображений AV1, а точнее файлов AVIF. Этот формат пришёл из видео и использует все его преимущества компрессии и обеспечивает более высокое качество картинок и детализацию при одинаковом размере с JPG. Сможем ли снимать фото в таком формате?

Compatible Media Transcoding

В Android 12 появляется возможность для любого приложения воспроизводить современные форматы видео, которые могут записать устройства без всяких проблем. Android сможет конвертировать HEVC (H.265) to AVC (H.264), а также HDR10 в SDR. Вам надо создать новый XML файл в ресурсах вашего приложения с описанием поддержки современных форматов, а затем добавить ссылку на него в AndroidManifest.



    
    
    

Новая функция позволяет устройствам создать видео в современных форматах на устройствах и преобразовывать его автоматически для отсутствия проблем использования такого контента у приложений.

Скорость конвертации видео довольно быстрая — ролик длиной одну минуту в разрешение 1080p 30 кадров в секунду конвертируется 9 секунд на Pixel 4. Напомню, что в Pixel 4 стоит флагманский процессор Snapdragon 845 и 6 гигов оперативы. Так что результаты на середнячках могут быть хуже (

Performance Class

b68a779f48d7ec127f8553e5b520747e.jpg

Начиная с Android 12, появляется новый стандарт Performance Class. Он описывает набор возможностей устройства, который являются минимальный требуемой для версии Android. Разработчики могут проверить класс производительности и изменить настройки, чтобы предоставлять лучший пользовательский опыт для устройства пользователя.

if (Build.VERSION.MEDIA_PERFORMANCE_CLASS >= Build.VERSION_CODES.S) {
   // Provide the most premium experience for highest performing devices
   ...
}
else if (Build.VERSION.MEDIA_PERFORMANCE_CLASS == Build.VERSION_CODES.R)
   // Provide a  high quality experience
   ...
}
else {
   // Remove extras to keep experience functional
   ...
}

Class 12 будет опубликован с релизом Android 12 и будет включать в себя требования по возможностям проигрывания видео, возможности съемки контента, а также характеристики дисплея, скорости чтения/записи на диск и оперативной памяти. С каждой новой версией будет повышаться класс и обновляться требования, но даже на Android 13 может остаться class 12, если не будет соответствия новым требованиям.

Прочее

  • Генерации видроотдачи на основе аудио потока. Очень полезна будет для игр

  • Добавили возможность использовать камеры с высоким разрешением т.е. делать сразу снимки 108 мегапикселей и других огромных размеров.

  • При переключении аудио между приложениями будет происходить затухание громкости, а не резкая пауза

  • Camera2 API теперь содержит расширения для использования спец режимов аналогично CameraX Extentions

Безопасность и приватность

Примерное местоположение

6023bf3ef2e56d1999a60d0a607720f7.gif

В Android 11 появилась возможность давать разрешение на доступ к геолокации только во время использования приложения и на один раз. Этими возможностями воспользовалось 80% пользователей. Google развивает идею контроля пользователем доступа приложений к местоположению. В Android можно запросить точное и примерное местоположение, так вот теперь при запросе точной позиции, пользователь может отказать, но выдать доступ к примерному местоположению.

Изменение будет действовать только для приложений с targetSdk=S, так как разработчикам приложений, запрашивающих доступ к точному местоположению надо поменять свой код обработке получения.

val locationPermissionRequest = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        when {
            permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
                // Точное местоположение
            }
            permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
                // Примерное местоположение
            } else -> {
                // Нет доступа к локации
            }
        }
    }

// ...

locationPermissionRequest.launch(
    arrayOf(
       Manifest.permission.ACCESS_FINE_LOCATION,
       Manifest.permission.ACCESS_COARSE_LOCATION
    )
)
5165d47b7b4c821c80df1cc667e2a6dd.jpg

Если вам всё же нужно точное местоположение, а пользователь ранее уже выдал примерное, то при повторном запросе пользователю будет предложено дать вам доступ только на точное местоположение.

Отдельное разрешение для Nearby сканирования через Bluetooth

В текущих версиях Android если вы хотите сканировать устройство поблизости с помощью Bluetooth, то вам приходилось запрашивать разрешение на доступ к местоположению, что порой вводило в заблуждение пользователей. Наконец-то в Android 12 эти разрешения будут отделены в новые: BLUETOOTH_SCAN и BLUETOOTH_CONNECT. BLUETOOTH_SCAN используется для доступа в случае поиска Bluetooth устройств, а BLUETOOTH_CONNECT — когда вам надо подключиться к устройствам с которыми уже связанными устройствами.

Если на основе сканирования вам всё также будет нужен доступ к местоположению, тогда без запроса на доступ к местоположению вам не обойтись.

Exact alarm permission

00d5ffebd303e2dc8580ec47c5cb38ec.jpg

Выполнение операций в заданное время — боль Android разработчиков. Каждый из них делает свои оптимизации энергопотребления, которые заставляют на каждой оболочке отключать их по своему, а приложение должно показать инструкцию. Возможно нас ждёт улучшение в работе точного срабатывания alarm-ов, так как теперь в системе появится разрешение SCHEDULE_EXACT_ALARM, без получения которого вызовы exact alram-ов в AlarmManager будет приводить к выбрасыванию SecurityException.

Новый permission не является runtime, а это значит что за его получением придется отправлять пользователя в настройки системы.

Приложения должны использовать новый тип alarm-ов только если это критический функционал. Например, будильники или таймеры, а также приложения, которые содержат функционал с требованием вызывать в точное время. Возможно даже в Google Play не станут допускать все приложения.

// Пример открытия настроек excat alarm для приложения  
if (!alarmManager.canScheduleExactAlarms()) {
    startActivityForResult(
        Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM, "package:")
    )
}

Отслеживание доступа к Clipboard

Теперь система следит за доступом к буферу обмена, и когда фоновое приложение будет пытаться оттуда получить данные будет выдано уведомление. Хорошее нововведение, которое не даст следить за вашими данными. Часто используйте copy-paste для важных данных? Я вот порой пользуюсь для паролей и стало немного страшно что может делаться сейчас.

Ограничения на использование Foreground Service

Главное изменение Android 12, которое доставит работы Android разработчикам — теперь Foreground Service нельзя запустить из фона, за исключением нескольких случаев. В случае неудачно попытке запуска Service приложение будет падать с исключением ForegroundServiceStartNotAllowedException.

Какие случае исключительные:

  • High Priority Push

  • Как реакция на broadcast-ы ACTION_BOOT_COMPLETED, ACTION_LOCKED_BOOT_COMPLETED, или ACTION_MY_PACKAGE_REPLACED

  • Приложение имеет специальные разрешения или роли

  • Приложение игнорирует оптимизации батареи

  • Exact alarm

и некоторый другие специфичные случаи

На замену предлагается использовать новое API Expedited Jobs, которое уже было добавлено в WorkManager 2.7.0. На Android 12 и более поздних версиях будет вызывать соответствующие API из JobScheduler, а на старых версиях Android будет запускаться Foreground Service.

OneTimeWorkRequestBuilder().apply {
    setInputData(inputData)
    setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
}.build()

Expedited job позволяет приложение выполнять короткие важные задачи, предоставляя системе лучшее управление доступом к ресурсам. Expedited Job по своим характеристикам находится между Foreground Service и обычной job из JobScheduler:

  • Короткий период — пара минут. Если ваша job будет выполняться дольше, система может остановить выполнение expedited job.

  • Expedited job менее подвержены эффектам от менеджмента системой экономии расхода батареи, таких как Battery Saver и Doze Mode.

  • Система запускает expedited job сразу же, если в системе имеется достаточно для этого ресурсов и количество уже запущенных job не превышает лимит, установленный в системе, и в хватает свободной оперативной памяти. Эти требования более строгие чем для других типов job.

Уведомления Foregroun Service будут показываться с задержкой

Как часто вы видите уведомления, которые появляются на пару секунд и исчезают? Может вы сами делали такие своим кодом? Бывалый разработчик знает что это Foreground Service, который выполняет свою работу быстро и поэтому уведомление показывается и быстро исчезает. В Android 12 уведомление, связанное с Foreground Service, не будет показываться в течении первых 5 секунд. Улучшение направлено на UX и надеюсь что будет позитивно воспринято пользователям. Конечно же есть исключения из правила, например, если у уведомления есть кнопки действий, то оно будет показано сразу. Разработчик может явно указать что уведомление нужно показать сразу c помощью нового API в Notification.Builder.setForegroundServiceBehavior ().

Notification.Builder(context)
         .setForegroundServiceBehavior(Notification.BEHAVIOR_IMMEDIATE_DISPLAY)
         .build();

Индикатор использования микрофона и камеры

6d57c7702ec6b97151e75a025c693691.gif

Современные версии Android и iOS активно заимствуют идеи друг у друга, так вот и новая возможность системы реализована аналогично iOS. Когда приложения будут использовать камеру или микрофон, то в status bar будет появляться индикатор, который не позволит делать что-то в фоне. Помимо прочего пользователь в любой момент сможет отключить доступ к камере и микрофону всем приложениям, с помощью тоглов.

Privaсy Dashboard

Новая функциональность Android 12 позволит пользователям видеть история доступа всеми приложениями к местоположению, микрофону и камере. Функционал будет доступен во второй Beta.

Гибернация приложений

В Android 11 автоматический сброс разрешений неиспользуемым приложениям зашёл успешно и держите развитие фичи — гибернация приложений. Если пользователь не будет взаимодействовать с вашим приложением очень долго (несколько месяцев), то система сбросит все полученные разрешения и отправит его в гибернацию:

  • Будет очищен кэш приложения

  • Приложение не сможет запускать job или alert в фоне

  • Приложение не будет получать push уведомления, включая high-priority FCM

После первого взаимодействия с вашим приложением все ограничения будут сняты, но вам надо будет заново создать job, alarm и уведомления, которые вам необходимы. Поведение схоже когда пользователь принудительно останавливает приложения в настройках

Вы можете запросить у пользователя отключить настройку «Отзывать разрешения и очищать память» в настройках, если ваше приложение подразумевает работу в фоне, например отправка местоположения между членами семьи или приложения для устройства-компаньона.

Ограничение частоты получения данных с сенсоров движения

По умолчанию данные с различных сенсоров, таких как акселерометр, гироскоп и других будут приходить с частотой 200 Гц или реже. Чтобы вы смогли получать данные как прежде вам надо в манифесте декларировать новое разрешение HIGH_SAMPLING_RATE_SENSORS, но запрашивать у пользователя его не придётся.

Объявление exported у всех компонентов в Manifest

Для всех компонентов в AndroidManifest теперь вы должны явно объявлять значение android:exported=true|false, который отвечает за доступность компонента другим приложениям. По умолчанию значение этого атрибута false, но если хотя один intent-filter будет объявлен у компонента, то значение поменяется на true. Такое уязвимостью пользовались злоумышленники, например в Slack.

6f35d7a102d78702b0a91188873615f2.png

В случае если у вас будет targetSdk=S и у какого-то компонента не будет объявлено значение exported, то установка не завершится, а в Logcat вы увидите сообщение.

Installation did not succeed.
The application could not be installed: INSTALL_FAILED_VERIFICATION_FAILURE
List of apks:
[0] '...app-debug.apk'
Installation failed due to: 'null'

Android Studio 2020.3.1 Arctic Fox содержит Android Lint проверки для того чтобы вы не пропустили ничего. Важно чтобы обновились сторонние библиотеки, которые содержат компоненты. В противном случае вам нужно будет использовать возможности Manifest Merger и задать значение exported самостоятельно.

Прочие

Много интересных изменений произошло в Android 12, но вместить все их в видео я не смогу, так что ловите ещё изменений в быстром формате:

  • ART теперь обновляется независимо от системы

  • В стандартном Build классе появились новые константы, которые позволяют получить производителя чипа и его модель (подробности).

  • Появился новый App Standby bucket — Restrictive. Он будет являться самым строгим и будет иметь больше всего ограничений

  • Удалены Bouncy Castle реализации криптографических алгоритмов

  • Backup и восстановление данных разделили для локального бэкапа (по проводу) и облачного, а также обновили возможности конфигурации.

  • При создании любого PendingIntent теперь явно нужно указывать мутабельный он или нет

  • Улучшения поведения в PiP и новые возможности

  • Web intent теперь будет открываться в приложении только если приложение является одобренным этим доменом. Используйте Android App Links, либо открывать системные настройки приложения и просить пользователя добавить domain в одобренные

  • Поддержка SameSite куков в WebView

  • Private Compute Core — изолированная от ОС среда для процессинга данных пользователя. Например, Smart Reply. У неё нет доступа к инету и исходный код открыт. Идея в том чтобы обрабатывать данные пользователя на устройстве без возможности их утечки куда-либо.

  • Возмжность приложения автоматически обновлять другие приложения. Раньше это мог делать только Google Play

Выход Android 12 запланирован на осень этого года, но еще до этого времени нас жжёт несколько Beta версий, которые порадуют новинками, показанными на Google I/O. Помните, что с выходом Android 12 надо будет адаптировать свои приложения под Android 11. В комментариях я жду ваших впечатлений от Android 12: что понравилось, что нет, а чего еще ждали от обновления зеленого робота.

© Habrahabr.ru