Функции и 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 Sake

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

Bluetooth

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

  • Поддержка стандарта AVRCP 1.4, который позволяет просмотреть песню.
  • Поддержка Bluetooth с низкой энергией (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 автоматически изучает все эти шаблоны в соответствии с персонализированными предпочтениями пользователей.

Smart Sharing работает для типов контента, кроме image , таких как audio , video , text , URL и т. Д.

Чтобы включить Smart Sharing, добавьте 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
);

Для получения подробной информации об анонациях обмена умными обменами см. EXTRA_CONTENT_ANNOTATIONS .

Текстовый классификатор

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

Доступность

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

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

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

Разрешения

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

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

Эти разрешения классифицируются как опасные и оба являются частью группы разрешений PHONE .

Доступ к новой учетной записи и APIS Discovery

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 Discovery см. Ссылку для AccountManager и OnAccountsUpdateListener .

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

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

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

Забежать против процессов приложения без декорации

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

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

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

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

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

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

Издеваться над тестами

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

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

Время выполнения и инструменты

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

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

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

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

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

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

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

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

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

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

API API -уровень Android Версия ICU Версия CLDR Версия Unicode
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, см. International на Android .

Android Enterprise

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

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

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