Функции и API Android 8.0

Android 8.0 (уровень API 26) представляет множество новых функций и возможностей для пользователей и разработчиков. В этом документе описываются новые возможности для разработчиков.

Обязательно ознакомьтесь с изменениями в поведении Android 8.0, чтобы узнать об областях, в которых изменения платформы могут повлиять на ваши приложения.

Пользовательский опыт

Режим «картинка в картинке»

Картинка в картинке в Android 8.0.

Android 8.0 (уровень API 26) позволяет запускать действия в режиме «картинка в картинке» (PIP) . PIP — это особый тип многооконного режима, который чаще всего используется для воспроизведения видео. Режим PIP изначально был доступен только для Android TV; Android 8.0 делает эту функцию доступной на других устройствах Android.

Когда действие находится в режиме PIP, оно находится в состоянии паузы, но должно продолжать отображать контент. По этой причине вам следует убедиться, что ваше приложение не приостанавливает воспроизведение в своем обработчике onPause() . Вместо этого вам следует приостановить видео в onStop() и возобновить воспроизведение в onStart() . Дополнительные сведения см. в разделе «Жизненный цикл многооконного режима» .

Чтобы указать, что ваша активность может использовать режим PIP, установите android:supportsPictureInPicture значение true в манифесте. (Начиная с Android 8.0, PIP не требует атрибута манифеста android:resizeableActivity . Однако вы должны установить android:resizeableActivity значение true, если ваша активность поддерживает другие многооконные режимы .)

В Android 8.0 (уровень API 26) представлен новый объект PictureInPictureParams , который вы передаете методам PIP, чтобы указать, как действие должно вести себя в режиме PIP. Этот объект определяет такие свойства, как предпочтительное соотношение сторон действия.

Существующие методы PIP, описанные в разделе «Добавление картинки в картинке», теперь можно использовать на всех устройствах Android, а не только на Android TV. Кроме того, Android 8.0 предоставляет следующие методы поддержки режима PIP:

  • Activity.enterPictureInPictureMode(PictureInPictureParams args) : переводит действие в режим «картинка в картинке». Соотношение сторон действия и другие параметры конфигурации задаются args . Если какие-либо поля в args пусты, система использует значения, установленные при последнем вызове Activity.setPictureInPictureParams() .

    Указанное действие размещается в углу экрана; остальная часть экрана заполнена предыдущим действием, которое было на экране. Действие, входящее в режим PIP, переходит в состояние паузы, но остается запущенным. Если пользователь касается действия PIP, система отображает меню, с которым пользователь может взаимодействовать; никакие события касания не достигают активности, пока она находится в состоянии PIP.

  • Activity.setPictureInPictureParams() : обновляет настройки конфигурации PIP действия. Если действие в данный момент находится в режиме PIP, настройки обновляются; это полезно, если изменяется соотношение сторон действия. Если действие не находится в режиме PIP, эти параметры конфигурации используются независимо от метода enterPictureInPictureMode() , который вы вызываете.

Уведомления

В Android 8.0 (уровень API 26) мы изменили дизайн уведомлений, чтобы обеспечить более простой и последовательный способ управления поведением и настройками уведомлений. Эти изменения включают в себя:

    Меню уведомлений при длительном нажатии в Android 8.0 (уровень API 26).

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

  • Каналы уведомлений. В Android 8.0 представлены каналы уведомлений, которые позволяют создавать настраиваемый пользователем канал для каждого типа уведомлений, которые вы хотите отображать. Пользовательский интерфейс называет каналы уведомлений категориями уведомлений . Чтобы узнать, как реализовать каналы уведомлений, см. Управление каналами уведомлений .
  • Точки уведомлений. В Android 8.0 появилась поддержка отображения точек или значков на значках запуска приложений. Точки уведомлений отражают наличие уведомлений, которые пользователь еще не закрыл или не выполнил никаких действий. Чтобы узнать, как работать с точками уведомлений, см. Значки уведомлений .
  • Откладывание: пользователи могут отложить уведомления, в результате чего они исчезнут на некоторое время, прежде чем появиться снова. Уведомления появляются снова с тем же уровнем важности, с которым они появлялись впервые. Приложения могут удалять или обновлять отложенное уведомление, но обновление отложенного уведомления не приводит к его повторному появлению.
  • Таймауты уведомлений: вы можете установить таймаут при создании уведомления с помощью setTimeoutAfter() . Вы можете использовать этот метод, чтобы указать продолжительность, по истечении которой уведомление должно быть отменено. При необходимости вы можете отменить уведомление до истечения указанного времени ожидания.
  • Настройки уведомлений. Вы можете вызвать setSettingsText() чтобы установить текст, который появляется, когда вы создаете ссылку на настройки уведомлений вашего приложения из уведомления, используя намерение Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES . Система может предоставлять следующие дополнительные возможности с целью фильтрации настроек, которые ваше приложение должно отображать пользователям: EXTRA_CHANNEL_ID , NOTIFICATION_TAG и NOTIFICATION_ID .
  • Отклонение уведомлений: пользователи могут сами отклонять уведомления, а приложения могут удалять их программным способом. Вы можете определить, когда уведомление будет отклонено и почему оно будет отклонено, реализовав метод onNotificationRemoved() из класса NotificationListenerService .
  • Цвета фона: вы можете установить и включить цвет фона для уведомления. Эту функцию следует использовать только в уведомлениях о текущих задачах, которые крайне важны для того, чтобы пользователь мог сразу их увидеть. Например, вы можете установить цвет фона для уведомлений, касающихся маршрутов движения или текущего телефонного звонка. Вы также можете установить желаемый цвет фона с помощью setColor() . Это позволит вам использовать setColorized() , чтобы включить использование цвета фона для уведомления.
  • Стиль сообщений. В Android 8.0 уведомления, использующие класс MessagingStyle , отображают больше контента в свернутом виде. Вам следует использовать класс MessagingStyle для уведомлений, связанных с обменом сообщениями. Вы также можете использовать метод addHistoricMessage() для предоставления контекста разговору, добавляя исторические сообщения в уведомления, связанные с обменом сообщениями.

Система автозаполнения

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

Android 8.0 (уровень API 26) упрощает заполнение форм, таких как формы входа и кредитной карты, благодаря внедрению платформы автозаполнения. Существующие и новые приложения работают с Autofill Framework после того, как пользователь разрешил автозаполнение.

Вы можете предпринять некоторые шаги, чтобы оптимизировать работу вашего приложения с платформой. Дополнительные сведения см. в разделе Обзор платформы автозаполнения .

Загружаемые шрифты

Android 8.0 (уровень API 26) и библиотека поддержки Android 26 позволяют запрашивать шрифты из приложения поставщика вместо того, чтобы объединять шрифты в APK или позволять APK загружать шрифты. Эта функция уменьшает размер APK-файла, увеличивает вероятность успешной установки приложения и позволяет нескольким приложениям использовать один и тот же шрифт.

Дополнительную информацию о загрузке шрифтов см. в разделе «Загружаемые шрифты» .

Шрифты в XML

В Android 8.0 (уровень API 26) представлена ​​новая функция «Шрифты в XML», которая позволяет использовать шрифты в качестве ресурсов. Это означает, что нет необходимости объединять шрифты в качестве ресурсов. Шрифты компилируются в файл R и автоматически доступны в системе как ресурс. Затем вы сможете получить доступ к этим шрифтам с помощью нового типа ресурса — font .

Библиотека поддержки 26 обеспечивает полную поддержку этой функции на устройствах с API версии 14 и выше.

Дополнительные сведения об использовании шрифтов в качестве ресурсов и получении системных шрифтов см. в разделе Шрифты в XML .

Автоматическое изменение размера TextView

Android 8.0 (уровень API 26) позволяет автоматически устанавливать размер расширяемого или сжимаемого текста в зависимости от размера TextView. Это означает, что гораздо проще оптимизировать размер текста на разных экранах или при использовании динамического контента. Дополнительные сведения об автоматическом изменении размера TextView в Android 8.0 см. в разделе Автоматическое изменение размера TextView .

Адаптивные иконки

В Android 8.0 (уровень API 26) представлены адаптивные значки запуска. Адаптивные значки поддерживают визуальные эффекты и могут отображать различные формы на разных моделях устройств. Чтобы узнать, как создавать адаптивные значки, см. руководство по адаптивным значкам .

Управление цветом

Разработчики Android-приложений для работы с изображениями теперь могут воспользоваться преимуществами новых устройств с дисплеем с широкой цветовой гаммой. Чтобы отображать изображения с широкой гаммой, приложениям необходимо будет включить флаг в своем манифесте (для каждого действия) и загружать растровые изображения со встроенным широким цветовым профилем (AdobeRGB, Pro Photo RGB, DCI-P3 и т. д.).

API веб-представления

Android 8.0 предоставляет несколько API, которые помогут вам управлять объектами WebView , отображающими веб-контент в вашем приложении. Эти API, которые улучшают стабильность и безопасность вашего приложения, включают следующее:

  • Версия API
  • Google API безопасного просмотра
  • API дескриптора завершения
  • API важности рендерера

Чтобы узнать больше о том, как использовать эти API, см. Управление WebViews .

Класс WebView теперь включает API безопасного просмотра для повышения безопасности просмотра веб-страниц. Дополнительную информацию см. в разделе Google Safe Browsing API.

Закрепление ярлыков и виджетов

В Android 8.0 (уровень API 26) реализовано закрепление ярлыков и виджетов в приложении. В своем приложении вы можете создавать закрепленные ярлыки и виджеты для поддерживаемых средств запуска с разрешения пользователя.

Дополнительную информацию см. в руководстве по функциям закрепления ярлыков и виджетов .

Максимальное соотношение сторон экрана

В Android 8.0 (уровень API 26) внесены изменения в настройку максимального соотношения сторон приложения.

Во-первых, в Android 8.0 появился атрибут maxAspectRatio , который можно использовать для установки максимального соотношения сторон вашего приложения. Кроме того, в Android 8.0 и более поздних версиях максимальное соотношение сторон приложения по умолчанию — это собственное соотношение сторон устройства, на котором приложение работает.

Дополнительные сведения об объявлении максимального соотношения сторон см. в разделе «Поддержка нескольких экранов» .

Поддержка нескольких дисплеев

Начиная с Android 8.0 (уровень API 26), платформа предлагает расширенную поддержку нескольких дисплеев. Если действие поддерживает многооконный режим и выполняется на устройстве с несколькими дисплеями, пользователи могут перемещать действие с одного дисплея на другой. Когда приложение запускает действие, оно может указать, на каком дисплее должно выполняться действие.

Примечание. Если действие поддерживает многооконный режим, Android 8.0 автоматически включает поддержку нескольких дисплеев для этого действия. Вам следует протестировать свое приложение, чтобы убедиться, что оно работает адекватно в среде с несколькими дисплеями.

В возобновленном состоянии одновременно может находиться только одно действие, даже если в приложении имеется несколько дисплеев. Деятельность с фокусом находится в возобновленном состоянии; все остальные видимые действия приостанавливаются, но не прекращаются. Дополнительные сведения о жизненном цикле действия, когда видны несколько действий, см. в разделе Многооконный жизненный цикл .

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

ActivityOptions предоставляет два новых метода для поддержки нескольких дисплеев:

setLaunchDisplayId()
Указывает, на каком дисплее должно отображаться действие при его запуске.
getLaunchDisplayId()
Возвращает текущий экран запуска действия.

Оболочка adb расширена для поддержки нескольких дисплеев. Команду shell start теперь можно использовать для запуска действия и указания целевого отображения действия:

adb shell start <activity_name> --display <display_id>

Унифицированные поля и отступы макета

Android 8.0 (уровень API 26) упрощает определение ситуаций, когда противоположные стороны элемента View используют одинаковые поля или отступы. В частности, теперь вы можете использовать следующие атрибуты в XML-файлах макета:

Примечание. Если вы настраиваете логику своего приложения для поддержки разных языков и культур , включая направление текста, имейте в виду, что эти атрибуты не влияют на значения layout_marginStart , layout_marginEnd , paddingStart или paddingEnd . Вы можете установить эти значения самостоятельно в дополнение к новым атрибутам вертикального и горизонтального макета, чтобы создать поведение макета, зависящее от направления текста.

Захват указателя

Некоторые приложения, такие как игры, удаленный рабочий стол и клиенты виртуализации, получают большую выгоду от контроля над указателем мыши. Захват указателя — это новая функция Android 8.0 (уровень API 26), которая обеспечивает такой контроль, передавая все события мыши в сфокусированное представление в вашем приложении.

Начиная с Android 8.0, View в вашем приложении может запрашивать захват указателя и определять прослушиватель для обработки захваченных событий указателя. В этом режиме указатель мыши скрыт. Представление может освободить захват указателя, когда ему больше не нужна информация о мыши. Система также может отключить захват указателя, когда представление теряет фокус, например, когда пользователь открывает другое приложение.

Информацию о том, как использовать эту функцию в вашем приложении, см. в разделе Захват указателя .

Категории приложений

Android 8.0 (уровень API 26) позволяет каждому приложению объявлять категорию, к которой оно относится, если это необходимо. Эти категории используются для кластеризации приложений схожего назначения или функции при их представлении пользователям, например, в разделах «Использование данных», «Использование батареи» или «Использование хранилища». Вы можете определить категорию для своего приложения, установив атрибут android:appCategory в теге манифеста <application> .

лаунчер Android ТВ

Android 8.0 (уровень API 26) включает новый ориентированный на контент домашний экран Android TV , который доступен с эмулятором Android TV и образом устройства Nexus Player для Android 8.0. На новом главном экране видеоконтент упорядочен по строкам, соответствующим каналам, каждый из которых заполнен программами с помощью приложения в системе. Приложения могут публиковать несколько каналов, и пользователи могут настраивать, какие каналы они хотят видеть на главном экране. На главном экране Android TV также есть строка «Смотреть дальше», которая заполняется программами из приложений в зависимости от привычек пользователя к просмотру. Приложения также могут предоставлять предварительный просмотр видео, которые автоматически воспроизводятся, когда пользователь фокусируется на программе. API-интерфейсы для заполнения каналов и программ являются частью API-интерфейсов TvProvider, которые распространяются как модуль библиотеки поддержки Android с Android 8.0.

АниматорНабор

Начиная с Android 8.0 (уровень API 26), API AnimatorSet теперь поддерживает поиск и воспроизведение в обратном порядке. Поиск позволяет установить положение анимации в определенный момент времени. Воспроизведение в обратном направлении полезно, если ваше приложение содержит анимацию действий, которые можно отменить. Вместо определения двух отдельных наборов анимаций вы можете воспроизвести один и тот же набор в обратном порядке.

Ввод и навигация

Клавиатурные навигационные кластеры

Если действие в вашем приложении использует сложную иерархию представлений, такую ​​как показанная на рис. 2, рассмотрите возможность организации групп элементов пользовательского интерфейса в кластеры для упрощения навигации между ними с помощью клавиатуры. Пользователи могут нажать Meta+Tab или Search+Tab на устройствах Chromebook, чтобы перейти от одного кластера к другому. Хорошими примерами кластеров являются: боковые панели, панели навигации, области основного контента и элементы, которые могут содержать множество дочерних элементов.

Пример действия, включающий пять навигационных кластеров, по которым пользователь может перемещаться с помощью сочетания клавиш навигационного кластера. Кластеры располагаются в следующем порядке: верхняя панель, левая боковая панель, область основного содержимого, нижняя панель и кнопка плавающего действия.
Рисунок 2. Активность, содержащая 5 навигационных кластеров

Чтобы сделать элемент View или ViewGroup кластером, установите для атрибута android:keyboardNavigationCluster значение true в XML-файле макета элемента или передайте true в setKeyboardNavigationCluster() в логике пользовательского интерфейса вашего приложения.

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

На устройствах с сенсорными экранами вы можете установить для элемента android:touchscreenBlocksFocus объекта ViewGroup , назначенного кластером, значение true , чтобы разрешить только кластерную навигацию в этот кластер и из него. Если вы примените эту конфигурацию к кластеру, пользователи не смогут использовать клавишу Tab или клавиши со стрелками для перехода в кластер или из него; вместо этого они должны нажать комбинацию клавиш кластерной навигации.

Посмотреть фокус по умолчанию

В Android 8.0 (уровень API 26) вы можете назначить View , которое должно получить фокус после возобновления (повторно) созданного действия и нажатия пользователем клавиши навигации на клавиатуре, например клавиши табуляции. Чтобы применить этот параметр «сфокусировано по умолчанию», установите для атрибута android:focusedByDefault элемента View значение true в XML-файле макета, содержащем элемент пользовательского интерфейса, или передайте true методу setFocusedByDefault() в логике пользовательского интерфейса вашего приложения.

Речевой вывод

Действия и службы могут использовать экземпляры TextToSpeech для диктовки и произнесения содержимого. Начиная с Android 8.0 (уровень API 26), ваше приложение может получать более точную информацию о времени, когда механизм преобразования текста в речь начинает произносить отдельные синтезированные слова, если механизм предоставляет эту информацию. Вы можете использовать эту функцию, чтобы привлечь внимание к конкретным словам, когда их произносит механизм преобразования текста в речь.

Чтобы использовать эти улучшения механизма преобразования текста в речь в своем приложении, зарегистрируйте экземпляр UtteranceProgressListener . В процессе регистрации включите обработчик метода onRangeStart() .

Механизм преобразования текста в речь вызывает rangeStart() , чтобы записать момент времени, в который он ожидает начала воспроизведения звука определенного диапазона текста. Когда аудио для этого текстового диапазона начинает воспроизводиться, выполняется метод onRangeStart() вашего приложения. Затем ваше приложение может ответить на этот обратный вызов, например, выделив текстовый диапазон, связанный с высказыванием.

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

Система

Новые детекторы StrictMode

В Android 8.0 (уровень API 26) добавлены три новых детектора StrictMode, которые помогут выявить потенциальные ошибки в вашем приложении:

  • detectUnbufferedIo() определит, когда ваше приложение читает или записывает данные без буферизации, что может существенно повлиять на производительность.
  • detectContentUriWithoutPermission() обнаружит, когда ваше приложение случайно забывает предоставить разрешения другому приложению при запуске действия вне вашего приложения.
  • detectUntaggedSockets() определит, когда ваше приложение выполняет сетевой трафик, без использования setThreadStatsTag(int) для маркировки вашего трафика в целях отладки.

Кэшированные данные

Android 8.0 (уровень API 26) обеспечивает лучшее руководство и поведение в отношении кэшированных данных. Каждому приложению теперь предоставляется квота дискового пространства для кэшированных данных, возвращаемая getCacheQuotaBytes(UUID) .

Когда системе необходимо освободить дисковое пространство, она начнет с удаления кэшированных файлов из приложений, которые превысили выделенную квоту. Таким образом, если вы сохраняете кэшированные данные в рамках выделенной квоты, ваши кэшированные файлы будут одними из последних в системе, которые будут очищаться при необходимости. Когда система решает, какие кэшированные файлы удалить внутри вашего приложения, она сначала рассматривает самые старые файлы (определяемые временем изменения).

Есть также два новых поведения, которые вы можете включить для каждого каталога, чтобы контролировать, как система освобождает ваши кэшированные данные:

  • StorageManager.setCacheBehaviorAtomic() можно использовать, чтобы указать, что каталог и все его содержимое должны быть удалены как одна атомарная единица.
  • setCacheBehaviorTombstone(File, boolean) можно использовать, чтобы указать, что вместо удаления файлов внутри каталога их следует усечь до 0 байт в длину, оставив пустой файл нетронутым.

Наконец, когда вам нужно выделить дисковое пространство для больших файлов, рассмотрите возможность использования нового API allocateBytes(FileDescriptor, long) , который будет автоматически очищать кэшированные файлы, принадлежащие другим приложениям (при необходимости), в соответствии с вашим запросом. Решая, достаточно ли на устройстве дискового пространства для хранения ваших новых данных, вызовите getAllocatableBytes(UUID) вместо использования getUsableSpace() , поскольку первый вариант будет учитывать любые кэшированные данные, которые система желает очистить от вашего имени.

Пейджинг контент-провайдера

Мы обновили поставщиков контента, включив в них поддержку загрузки большого набора данных по одной странице за раз. Например, приложение для работы с фотографиями, содержащее многие тысячи изображений, может запрашивать подмножество данных для представления на странице. Каждая страница результатов, возвращаемых поставщиком контента, представлена ​​одним объектом Cursor. И клиент, и поставщик должны реализовать пейджинг, чтобы использовать эту функцию.

Подробную информацию об изменениях в поставщиках контента см. в разделах ContentProvider и ContentProviderClient .

Запросы на обновление контента

Каждый из классов ContentProvider и ContentResolver теперь включает метод refresh() , благодаря которому клиентам будет проще узнать, актуальна ли запрашиваемая ими информация.

Вы можете добавить собственную логику обновления контента, расширив ContentProvider . Убедитесь, что вы переопределили метод refresh() , чтобы он возвращал true , указывая клиентам вашего провайдера, что вы пытались обновить данные самостоятельно.

Ваше клиентское приложение может явно запрашивать обновленный контент, вызывая другой метод, также называемый refresh() . При вызове этого метода передайте URI данных для обновления.

Примечание. Поскольку вы можете запрашивать данные по сети, вам следует вызывать refresh() со стороны клиента только тогда, когда есть явные признаки того, что контент устарел. Наиболее распространенной причиной выполнения этого типа обновления контента является ответ на жест пролистывания для обновления , явный запрос текущего пользовательского интерфейса для отображения актуального контента.

Улучшения JobScheduler

Android 8.0 (уровень API 26) представляет ряд улучшений в JobScheduler . Эти улучшения облегчают соответствие вашего приложения новым ограничениям фонового выполнения , поскольку вы обычно можете использовать запланированные задания для замены фоновых служб, которые теперь ограничены, или неявных приемников широковещательной передачи.

Обновления JobScheduler включают:

  • Теперь вы можете связать рабочую очередь с запланированным заданием. Чтобы добавить рабочий элемент в очередь заданий, вызовите JobScheduler.enqueue() . Когда задание выполняется, оно может удалить ожидающую работу из очереди и обработать ее. Эта функциональность обрабатывает многие варианты использования, которые раньше требовали запуска фоновой службы, особенно служб, реализующих IntentService .
  • Библиотека поддержки Android 26.0.0 представляет новый класс JobIntentService , который обеспечивает ту же функциональность, что и IntentService , но использует задания вместо служб при работе на Android 8.0 (уровень API 26) или выше.
  • Теперь вы можете вызвать JobInfo.Builder.setClipData() чтобы связать ClipData с заданием. Этот параметр позволяет связать разрешения URI с заданием аналогично тому, как эти разрешения могут передаваться в Context.startService() . Вы также можете использовать разрешения URI с намерениями в рабочих очередях.
  • Запланированные задания теперь поддерживают несколько новых ограничений:
    JobInfo.isRequireStorageNotLow()
    Задание не запускается, если на устройстве недостаточно свободного места.
    JobInfo.isRequireBatteryNotLow()
    Задание не запускается, если уровень заряда батареи находится на критическом пороге или ниже него; это уровень, на котором устройство отображает диалоговое окно системы предупреждения о низком заряде батареи .
    NETWORK_TYPE_METERED
    Для работы требуется лимитное сетевое подключение, как и в большинстве тарифных планов сотовой связи.

Пользовательское хранилище данных

Android 8.0 (уровень API 26) позволяет вам предоставить собственное хранилище данных для ваших предпочтений, что может быть полезно, если ваше приложение хранит настройки в облаке или локальной базе данных или если настройки зависят от устройства. Дополнительные сведения о реализации хранилища данных см. в разделе Пользовательское хранилище данных .

Улучшения мультимедиа

VolumeShaper

Появился новый класс VolumeShaper . Используйте его для выполнения коротких автоматических переходов громкости, таких как постепенное появление, затухание и перекрестное затухание. Дополнительную информацию см. в разделе «Управление амплитудой с помощью VolumeShaper» .

Улучшения фокусировки звука

Аудиоприложения совместно используют аудиовыход на устройстве, запрашивая и отказываясь от фокуса звука. Приложение обрабатывает изменения фокуса, запуская или останавливая воспроизведение или уменьшая его громкость. Появился новый класс AudioFocusRequest . Используя этот класс в качестве параметра requestAudioFocus() , приложения получают новые возможности при обработке изменений фокуса звука: автоматическое приглушение и отложенное усиление фокуса .

Медиа-метрики

Новый метод getMetrics() возвращает объект PersistableBundle , содержащий информацию о конфигурации и производительности, выраженную в виде карты атрибутов и значений. Метод getMetrics() определен для следующих медиа-классов:

Метрики собираются отдельно для каждого экземпляра и сохраняются на протяжении всего времени существования экземпляра. Если метрики недоступны, метод возвращает значение null. Фактические возвращаемые метрики зависят от класса.

Медиаплеер

Начиная с Android 8.0 (уровень API 26), MediaPlayer может воспроизводить материалы , защищенные DRM, и медиафайлы, зашифрованные на уровне образца HLS .

В Android 8.0 представлена ​​новая перегруженная команда seekTo() , которая обеспечивает детальный контроль при поиске кадра. Он включает второй параметр, определяющий режим поиска:

  • SEEK_PREVIOUS_SYNC перемещает позицию мультимедиа в синхронизирующий (или ключевой) кадр, связанный с источником данных, который расположен непосредственно перед или в данный момент времени.
  • SEEK_NEXT_SYNC перемещает позицию мультимедиа в синхронизирующий (или ключевой) кадр, связанный с источником данных, который расположен сразу после или в данный момент времени.
  • SEEK_CLOSEST_SYNC перемещает позицию мультимедиа в синхронизирующий (или ключевой) кадр, связанный с источником данных, который расположен ближе всего к данному времени или в данный момент.
  • SEEK_CLOSEST перемещает позицию мультимедиа в кадр ( не обязательно синхронизирующий или ключевой кадр ), связанный с источником данных, который расположен ближе всего к данному моменту времени или в данный момент.

При непрерывном поиске приложения должны использовать любой из режимов SEEK_ а не SEEK_CLOSEST , который работает относительно медленнее, но может быть более точным.

МедиаРекордер

  • MediaRecorder теперь поддерживает формат MPEG2_TS, который удобен для потоковой передачи:

    Котлин

    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS)
    

    Ява

    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
    

    см. MediaRecorder.OutputFormat

  • MediaMuxer теперь может обрабатывать любое количество аудио- и видеопотоков. Вы больше не ограничены одной аудиодорожкой и/или одной видеодорожкой. Используйте addTrack() чтобы микшировать столько треков, сколько захотите.
  • MediaMuxer также может добавить одну или несколько дорожек метаданных, содержащих определяемую пользователем покадровую информацию. Формат метаданных определяется вашим приложением. Дорожка метаданных поддерживается только для контейнеров MP4.

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

При добавлении дорожки метаданных ее формат mime должен начинаться с префикса «application/». Запись метаданных аналогична записи видео/аудиоданных, за исключением того, что данные не поступают из MediaCodec . Вместо этого приложение передает ByteBuffer со связанной с ним меткой времени методу writeSampleData() . Временная метка должна соответствовать той же временной базе, что и видео- и аудиодорожки.

Сгенерированный файл MP4 использует TextMetaDataSampleEntry определенный в разделе 12.3.3.2 ISOBMFF, для обозначения формата mime метаданных. При использовании MediaExtractor для извлечения файла с дорожкой метаданных MIME-формат метаданных будет извлечен в MediaFormat .

Улучшен доступ к медиафайлам.

Платформа доступа к хранилищу (SAF) позволяет приложениям предоставлять пользовательский DocumentsProvider , который может предоставлять доступ к файлам в источнике данных другим приложениям. Фактически, поставщик документов может даже предоставить доступ к файлам, которые находятся в сетевом хранилище или используют такой протокол, как протокол передачи мультимедиа (MTP) .

Однако доступ к большим медиафайлам из удаленного источника данных сопряжен с некоторыми проблемами:

  • Медиаплеерам требуется доступ к файлу от поставщика документов. В случаях, когда большой медиафайл находится в удаленном источнике данных, поставщик документов должен заранее получить все данные и создать дескриптор файла моментального снимка. Медиаплеер не может воспроизвести файл без дескриптора файла, поэтому воспроизведение не может начаться, пока поставщик документов не завершит загрузку файла.
  • Менеджеры коллекций мультимедиа, такие как приложения для фотографий, должны пройти ряд URI доступа, чтобы получить доступ к мультимедиа, хранящемуся на внешней SD-карте, через папки с заданной областью. Такой шаблон доступа делает массовые операции с носителями, такие как перемещение, копирование и удаление, довольно медленными.
  • Менеджеры коллекций носителей не могут определить местоположение документа по его URI. Из-за этого приложениям такого типа сложно предоставить пользователям возможность выбирать, где сохранить медиафайл.

Android 8.0 решает каждую из этих проблем, улучшая платформу доступа к хранилищу.

Пользовательские поставщики документов

Начиная с Android 8.0, Storage Access Framework позволяет поставщикам пользовательских документов создавать доступные для поиска файловые дескрипторы для файлов, находящихся в удаленном источнике данных. SAF может открыть файл, чтобы получить собственный дескриптор файла, доступный для поиска. Затем SAF доставляет запросы дискретных байтов поставщику документов. Эта функция позволяет поставщику документов возвращать точный диапазон байтов, запрошенный приложением медиаплеера, вместо предварительного кэширования всего файла.

Чтобы использовать эту функцию, вам необходимо вызвать новый метод StorageManager.openProxyFileDescriptor() . Метод openProxyFileDescriptor() принимает объект ProxyFileDescriptorCallback в качестве обратного вызова. SAF вызывает обратный вызов каждый раз, когда клиентское приложение выполняет файловые операции с файловым дескриптором, возвращенным от поставщика документов.

Прямой доступ к документам

Начиная с Android 8.0 (уровень API 26), вы можете использовать метод getDocumentUri() для получения URI, ссылающегося на тот же документ, что и заданный mediaUri . Однако, поскольку возвращенный URI поддерживается DocumentsProvider , менеджеры коллекций мультимедиа могут получить доступ к документу напрямую, без необходимости просматривать деревья каталогов с заданной областью. В результате медиа-менеджеры могут выполнять файловые операции с документом значительно быстрее.

Внимание: метод getDocumentUri() находит только медиа-файлы; он не предоставляет приложениям разрешение на доступ к этим файлам. Подробнее о том, как получить разрешение на доступ к медиафайлам, смотрите в справочной документации.

Пути к документам

При использовании Storage Access Framework в Android 8.0 (уровень API 26) вы можете использовать метод findDocumentPath() , доступный как в классах DocumentsContract , так и DocumentsProvider , для определения пути от корня файловой системы по идентификатору документа. Метод возвращает этот путь в объекте DocumentsContract.Path . В случаях, когда файловая система имеет несколько определенных путей к одному и тому же документу, метод возвращает путь, который чаще всего используется для доступа к документу с заданным идентификатором.

Эта функция особенно полезна в следующих сценариях:

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

Примечание. Если у вашего приложения есть разрешение на доступ только к некоторым документам в пути, возвращаемое значение findDocumentPath() включает только те папки и документы, к которым может получить доступ ваше приложение.

Мониторинг воспроизведения звука

Системный сервис AudioManager поддерживает список активных объектов AudioPlaybackConfiguration , каждый из которых содержит информацию о конкретном сеансе воспроизведения звука. Ваше приложение может получить набор активных в данный момент конфигураций, вызвав getActivePlaybackConfigurations() .

Начиная с Android 8.0 (уровень API 26), вы можете зарегистрировать обратный вызов, который уведомляет ваше приложение об изменении одного или нескольких объектов AudioPlaybackConfiguration . Для этого вызовите registerAudioPlaybackCallback() , передав экземпляр AudioManager.AudioPlaybackCallback . Класс AudioManager.AudioPlaybackCallback содержит метод onPlaybackConfigChanged() , который система вызывает при изменении конфигурации воспроизведения звука.

Возможности подключения

Поддержка Wi-Fi

В Android 8.0 (уровень API 26) добавлена ​​поддержка Wi-Fi Aware, основанная на спецификации Neighbor Awareness Networking (NAN). На устройствах с соответствующим оборудованием Wi-Fi Aware приложения и близлежащие устройства могут обнаруживать Wi-Fi и обмениваться данными через него без точки доступа в Интернет. Мы работаем с нашими партнерами по оборудованию, чтобы как можно скорее внедрить технологию Wi-Fi Aware на устройства. Информацию о том, как интегрировать Wi-Fi Aware в ваше приложение, см. в разделе Wi-Fi Aware .

Bluetooth

Android 8.0 (уровень API 26) расширяет поддержку Bluetooth платформы, добавляя следующие функции:

  • Поддержка стандарта AVRCP 1.4, который позволяет просматривать библиотеку песен.
  • Поддержка стандарта Bluetooth Low-Energy (BLE) 5.0.
  • Интеграция кодека Sony LDAC в стек Bluetooth.

Сопряжение с сопутствующими устройствами

Android 8.0 (уровень API 26) предоставляет API, которые позволяют настраивать диалоговое окно запроса на сопряжение при попытке сопряжения с сопутствующими устройствами через Bluetooth, BLE и Wi-Fi. Дополнительную информацию см. в разделе Сопряжение сопутствующих устройств .

Дополнительную информацию об использовании Bluetooth на Android см. в руководстве по Bluetooth . Информацию об изменениях Bluetooth, характерных для Android 8.0 (уровень API 26), см. в разделе Bluetooth на странице «Изменения поведения Android 8.0» .

Совместное использование

Умный обмен

Android 8.0 (уровень API 26) узнает о персонализированных настройках обмена пользователями и лучше понимает для каждого типа контента, какие приложения подходят для обмена. Например, если пользователь фотографирует чек, Android 8.0 может предложить приложение для отслеживания расходов; если пользователь делает селфи, приложение для социальных сетей может лучше обработать изображение. Android 8.0 автоматически запоминает все эти шаблоны в соответствии с персональными предпочтениями пользователей.

Интеллектуальный обмен работает для типов контента, отличных от image , таких как audio , video , text , URL и т. д.

Чтобы включить интеллектуальный общий доступ, добавьте ArrayList , содержащий до трех строковых аннотаций, к намерению, которое совместно использует содержимое. Аннотации должны описывать основные компоненты или темы содержания. В следующем примере кода показано, как добавить аннотации к намерению:

Котлин

val annotations: ArrayList<String> = arrayListOf(
        "topic1",
        "topic2",
        "topic3"
)

intent.putStringArrayListExtra(
        Intent.EXTRA_CONTENT_ANNOTATIONS,
        annotations
)

Ява

ArrayList<String> annotations = new ArrayList<>();

annotations.add("topic1");
annotations.add("topic2");
annotations.add("topic3");

intent.putStringArrayListExtra(
    Intent.EXTRA_CONTENT_ANNOTATIONS,
    annotations
);

Подробную информацию об аннотациях Smart Sharing см. в EXTRA_CONTENT_ANNOTATIONS .

Классификатор текста

На совместимых устройствах приложения могут использовать новый классификатор текста, чтобы проверять, соответствует ли строка известному типу объекта классификатора, и получать предлагаемые альтернативы выбора. Сущности, распознаваемые системой, включают адреса, URL-адреса, номера телефонов и адреса электронной почты. Для получения дополнительной информации см. TextClassifier .

Доступность

Android 8.0 (уровень API 26) поддерживает несколько новых функций специальных возможностей для разработчиков, создающих собственные службы специальных возможностей:

Чтобы узнать больше о том, как сделать ваше приложение более доступным, см. раздел «Доступность» .

Безопасность и конфиденциальность

Разрешения

В Android 8.0 (уровень API 26) представлено несколько новых разрешений, связанных с телефонией:

  • Разрешение ANSWER_PHONE_CALLS позволяет вашему приложению программно отвечать на входящие телефонные звонки. Чтобы обработать входящий телефонный звонок в вашем приложении, вы можете использовать метод acceptRingingCall() .
  • Разрешение READ_PHONE_NUMBERS предоставляет вашему приложению доступ на чтение телефонных номеров, хранящихся на устройстве.

Оба этих разрешения классифицируются как опасные и входят в группу разрешений PHONE .

Новые API доступа к учетной записи и обнаружения

В Android 8.0 (уровень API 26) представлено несколько улучшений в том, как приложения получают доступ к учетным записям пользователей. Для учетных записей, которыми они управляют, аутентификаторы могут использовать свою собственную политику, чтобы решить, следует ли скрывать учетные записи в приложении или раскрывать их для приложения. Система Android отслеживает приложения, которые могут получить доступ к определенной учетной записи.

В предыдущих версиях Android приложения, которые хотели отслеживать список учетных записей пользователей, должны были получать обновления обо всех учетных записях, включая учетные записи несвязанных типов. В Android 8.0 добавлен метод addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]) , который позволяет приложениям указывать список типов учетных записей, для которых следует получать изменения учетной записи.

Изменения API

AccountManager предоставляет шесть новых методов, помогающих аутентификаторам управлять тем, какие приложения могут видеть учетную запись:

В Android 8.0 (уровень API 26) представлены два специальных значения имени пакета для указания уровней видимости для приложений, которые не были установлены с помощью метода setAccountVisibility(android.accounts.Account, java.lang.String, int) . Значение видимости PACKAGE_NAME_KEY_LEGACY_VISIBLE применяется к приложениям, имеющим разрешение GET_ACCOUNTS и предназначенным для версий Android ниже Android 8.0 или чьи подписи соответствуют аутентификатору, ориентированному на любую версию Android. PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE предоставляет значение видимости по умолчанию для приложений, которые не были установлены ранее и к которым PACKAGE_NAME_KEY_LEGACY_VISIBLE неприменим.

Дополнительные сведения о новых API-интерфейсах доступа и обнаружения учетных записей см. в справочнике по AccountManager и OnAccountsUpdateListener .

Тестирование

Инструментальное тестирование

Android 8.0 (уровень API 26) предоставляет следующие дополнительные возможности для инструментальных тестов вашего приложения.

Запуск процессов приложения, не являющихся стандартными.

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

Чтобы определить инструментарий процесса, отличный от стандартного, перейдите к файлу манифеста, а затем к нужному элементу <instrumentation> . Добавьте атрибут android:targetProcess и установите для него одно из следующих значений:

  • Имя конкретного процесса.
  • Список имен процессов, разделенных запятыми.
  • Подстановочный знак ( "*" ), который позволяет инструменту запускаться в отношении любого запущенного процесса, выполняющего код в пакете, указанном в атрибуте android:targetPackage .

Пока выполняется инструментальный тест, вы можете проверить, какой процесс он тестирует, вызвав getProcessName() .

Сообщайте о результатах во время теста

Теперь вы можете сообщать результаты во время выполнения инструментального теста, а не после него, вызвав addResults() .

Макет намерений для тестов

Чтобы упростить создание изолированных, независимых тестов пользовательского интерфейса для действий вашего приложения, в Android 8.0 (уровень API 26) представлен метод onStartActivity() . Этот метод переопределяется в пользовательском подклассе класса Instrumentation.ActivityMonitor для обработки определенного намерения, которое вызывает ваш тестовый класс.

Когда ваш тестовый класс вызывает намерение, метод возвращает объект-заглушку Instrumentation.ActivityResult вместо выполнения самого намерения. Используя эту логику имитации намерения в своих тестах, вы можете сосредоточиться на том, как ваша активность подготавливает и обрабатывает намерение, которое вы передаете другому действию или совершенно другому приложению.

Среда выполнения и инструменты

Оптимизация платформы

Android 8.0 (уровень API 26) обеспечивает оптимизацию среды выполнения и другие оптимизации платформы, что приводит к ряду улучшений производительности. Эти оптимизации включают в себя сбор мусора с одновременным сжатием, более эффективное использование памяти и локальность кода.

Эти оптимизации приводят к ускорению загрузки, а также повышению производительности как ОС, так и приложений.

Обновленная поддержка языка Java.

В Android 8.0 (уровень API 26) добавлена ​​поддержка нескольких дополнительных API OpenJDK Java:

Чтобы узнать больше о классах и методах этих недавно добавленных пакетов, см. справочную документацию по API.

Если вы хотите использовать функции языка Java 8 в Android Studio, вам следует загрузить последнюю предварительную версию .

Обновлены API ICU4J Android Framework.

Android 8.0 (уровень API 26) расширяет API-интерфейсы ICU4J Android Framework , которые являются подмножеством API-интерфейсов ICU4J, чтобы разработчики приложений могли использовать их в пакете android.icu . Эти API используют данные локализации, имеющиеся на устройстве, поэтому вы можете уменьшить объем APK, не компилируя библиотеки ICU4J в APK.

Таблица 1. Версии ICU, CLDR и Unicode, используемые в Android.

Уровень API Android версия отделения интенсивной терапии CLDR-версия Версия Юникод
Android 7.0 (уровень API 24), Android 7.1 (уровень API 25) 56 28 8.0
Android 8.0 (уровень API 26) 58,2 30.0.3 9,0

Дополнительные сведения об интернационализации в Android, включая поддержку ICU4J, см. в разделе Интернационализация в Android .

Android предприятие

Для устройств под управлением Android 8.0 (уровень API 26) были представлены новые корпоративные функции и API. Основные моменты включают следующее:

  • Рабочие профили на полностью управляемых устройствах позволяют предприятиям отделять работу от личных данных, одновременно управляя и тем, и другим.
  • Делегирование API позволяет владельцам устройств и владельцам профилей назначать управление приложениями другим приложениям.
  • Улучшения пользовательского опыта в процессе подготовки (включая новые параметры настройки) сокращают время установки.
  • Новые средства управления Bluetooth, Wi-Fi, резервным копированием и безопасностью позволяют предприятиям управлять большей частью устройства. Журналирование сетевой активности помогает предприятиям отслеживать проблемы.

Чтобы узнать больше об этих и других новых корпоративных API-интерфейсах и функциях Android, см. раздел Android на предприятии .