API-интерфейсы Android 4.0

Уровень API: 14

Android 4.0 ( ICE_CREAM_SANDWICH ) — это основная версия платформы, в которую добавлено множество новых функций для пользователей и разработчиков приложений. Помимо всех новых функций и API, обсуждаемых ниже, Android 4.0 является важным выпуском платформы, поскольку он переносит обширный набор API и голографических тем из Android 3.x на экраны меньшего размера. Как разработчик приложений, у вас теперь есть единая платформа и унифицированная платформа API, которая позволяет вам разрабатывать и публиковать свое приложение с помощью одного APK, который обеспечивает оптимизированный пользовательский интерфейс для мобильных телефонов, планшетов и т. д. при использовании одной и той же версии Android. Android 4.0 (уровень API 14) или более поздней версии.

Для разработчиков платформа Android 4.0 доступна в виде загружаемого компонента Android SDK. Загружаемая платформа включает в себя библиотеку Android и образ системы, а также набор скинов эмулятора и многое другое. Чтобы начать разработку или тестирование для Android 4.0, используйте Android SDK Manager, чтобы загрузить платформу в свой SDK.

Обзор API

В разделах ниже представлен технический обзор новых API в Android 4.0.

Социальные API в поставщике контактов

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

Профиль пользователя

Android теперь включает личный профиль, который представляет владельца устройства, как определено в таблице ContactsContract.Profile . Социальные приложения, сохраняющие личность пользователя, могут внести свой вклад в данные профиля пользователя, создав новую запись ContactsContract.RawContacts в ContactsContract.Profile . То есть необработанные контакты, представляющие пользователя устройства, не принадлежат традиционной таблице необработанных контактов, определенной ContactsContract.RawContacts Uri; вместо этого вы должны добавить необработанный контакт профиля в таблицу CONTENT_RAW_CONTACTS_URI . Необработанные контакты в этой таблице затем объединяются в единый видимый пользователю профиль с надписью «Я».

Для добавления нового необработанного контакта в профиль требуется разрешение android.Manifest.permission#WRITE_PROFILE. Аналогично, чтобы читать таблицу профиля, вы должны запросить разрешение android.Manifest.permission#READ_PROFILE. Однако большинству приложений не требуется читать профиль пользователя, даже при добавлении данных в профиль. Чтение профиля пользователя — это конфиденциальное разрешение, и следует ожидать, что пользователи будут скептически относиться к приложениям, которые его запрашивают.

Пригласить намерение

Действие намерения INVITE_CONTACT позволяет приложению вызвать действие, которое указывает, что пользователь хочет добавить контакт в социальную сеть. Приложение, получающее приложение, использует его для приглашения указанного контакта в эту социальную сеть. Большинство приложений будут получать эту операцию. Например, встроенное приложение «Люди» вызывает намерение приглашения, когда пользователь выбирает «Добавить соединение» для определенного социального приложения, указанного в контактных данных человека.

Чтобы ваше приложение было видимым в списке «Добавить соединение», ваше приложение должно иметь адаптер синхронизации для синхронизации контактной информации с вашей социальной сетью. Затем вы должны указать системе, что ваше приложение отвечает на намерение INVITE_CONTACT , добавив атрибут inviteContactActivity в файл конфигурации синхронизации вашего приложения с полным именем действия, которое система должна запустить при отправке намерения приглашения. Запускаемое действие затем может получить URI для рассматриваемого контакта из данных намерения и выполнить необходимую работу, чтобы пригласить этот контакт в сеть или добавить человека в соединения пользователя.

Большие фотографии

Android теперь поддерживает фотографии в высоком разрешении для контактов. Теперь, когда вы помещаете фотографию в запись контакта, система обрабатывает ее как в миниатюру размером 96x96 (как это было раньше), так и в «отображаемую фотографию» размером 256x256, которая сохраняется в новом файловом хранилище фотографий (точные размеры, которые выбор системы может измениться в будущем). Добавить к контакту большую фотографию можно, поместив большую фотографию в обычный столбец PHOTO строки данных, которую система затем обработает в соответствующую миниатюру и отобразит записи фотографий.

Контактная информация об использовании

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

Поставщик календаря

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

Различные приложения и виджеты могут использовать эти API для чтения и изменения событий календаря. Однако некоторые из наиболее привлекательных вариантов использования — это адаптеры синхронизации, которые синхронизируют календарь пользователя с другими службами календаря с поставщиком календаря, чтобы предложить единое расположение для всех событий пользователя. Например, события Календаря Google синхронизируются с поставщиком календаря с помощью адаптера синхронизации календаря Google, что позволяет просматривать эти события с помощью встроенного в Android приложения «Календарь».

Модель данных для календарей и информации, связанной с событиями, в поставщике календаря определяется CalendarContract . Все данные календаря пользователя хранятся в ряде таблиц, определенных различными подклассами CalendarContract :

  • Таблица CalendarContract.Calendars содержит информацию, относящуюся к календарю. Каждая строка в этой таблице содержит сведения об одном календаре, такие как имя, цвет, информация о синхронизации и т. д.
  • Таблица CalendarContract.Events содержит информацию, относящуюся к событию. Каждая строка в этой таблице содержит информацию об одном событии, например название события, место, время начала, время окончания и т. д. Событие может произойти один раз или повториться несколько раз. Участники, напоминания и расширенные свойства хранятся в отдельных таблицах и используют _ID события, чтобы связать их с событием.
  • Таблица CalendarContract.Instances содержит время начала и окончания возникновения события. Каждая строка в этой таблице представляет одно вхождение. Для одноразовых событий существует взаимно однозначное сопоставление экземпляров с событиями. Для повторяющихся событий автоматически создается несколько строк, соответствующих множественным повторениям этого события.
  • Таблица CalendarContract.Attendees содержит сведения об участниках или гостях мероприятия. Каждая строка представляет одного гостя мероприятия. Он определяет тип гостя и его реакцию на событие.
  • Таблица CalendarContract.Reminders содержит данные предупреждений/уведомлений. Каждая строка представляет одно оповещение о событии. Событие может иметь несколько напоминаний. Количество напоминаний на одно событие указывается в MAX_REMINDERS , который задается адаптером синхронизации, которому принадлежит данный календарь. Напоминания указываются в количестве минут до запланированного события и указывают метод сигнала тревоги, например использование оповещения, электронной почты или SMS для напоминания пользователю.
  • Таблица CalendarContract.ExtendedProperties содержит непрозрачные поля данных, используемые адаптером синхронизации. Поставщик не предпринимает никаких действий с элементами в этой таблице, кроме как удалять их при удалении связанных с ними событий.

Чтобы получить доступ к данным календаря пользователя с помощью поставщика календаря, ваше приложение должно запросить разрешение READ_CALENDAR (для доступа на чтение) и WRITE_CALENDAR (для доступа на запись).

Цель события

Если все, что вам нужно, — это добавить событие в календарь пользователя, вы можете использовать намерение ACTION_INSERT с данными, определенными Events.CONTENT_URI , чтобы запустить в приложении «Календарь» действие, создающее новые события. Использование намерения не требует какого-либо разрешения, и вы можете указать детали события со следующими дополнительными функциями:

Поставщик голосовой почты

Новый поставщик голосовой почты позволяет приложениям добавлять голосовые сообщения на устройство, чтобы представить все голосовые сообщения пользователя в одном визуальном представлении. Например, возможно, что у пользователя есть несколько источников голосовой почты, например один от поставщика услуг телефона, а другие от VoIP или других альтернативных голосовых служб. Эти приложения могут использовать API-интерфейсы поставщика голосовой почты для добавления своей голосовой почты на устройство. Затем встроенное приложение «Телефон» представляет пользователю все голосовые сообщения в единой презентации. Хотя системное приложение «Телефон» является единственным приложением, которое может читать все голосовые сообщения, каждое приложение, предоставляющее голосовую почту, может читать те, которые оно добавило в систему (но не может читать голосовую почту от других служб).

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

Класс VoicemailContract определяет поставщика контента для поставщика голосовой почты. Подклассы VoicemailContract.Voicemails и VoicemailContract.Status предоставляют таблицы, в которые приложения могут вставлять данные голосовой почты для хранения на устройстве. Пример приложения поставщика голосовой почты см. в Демо-версии поставщика голосовой почты .

Мультимедиа

В Android 4.0 добавлено несколько новых API-интерфейсов для приложений, которые взаимодействуют с мультимедийными данными, такими как фотографии, видео и музыка.

Медиа-эффекты

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

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

  1. Они должны быть привязаны к изображению текстуры GL_TEXTURE_2D
  2. Они должны содержать хотя бы один уровень MIP-карты.

Объект Effect определяет один медиаэффект, который можно применить к кадру изображения. Основной рабочий процесс создания Effect :

  1. Вызовите EffectContext.createWithCurrentGlContext() из контекста OpenGL ES 2.0.
  2. Используйте возвращенный EffectContext для вызова EffectContext.getFactory() , который возвращает экземпляр EffectFactory .
  3. Вызовите createEffect() , передав ему имя эффекта из @link android.media.effect.EffectFactory}, например EFFECT_FISHEYE или EFFECT_VIGNETTE .

Вы можете настроить параметры эффекта, вызвав setParameter() и передав имя и значение параметра. Каждый тип эффекта принимает разные параметры, которые указаны в названии эффекта. Например, EFFECT_FISHEYE имеет один параметр для scale искажения.

Чтобы применить эффект к текстуре, вызовите apply() для Effect и передайте входную текстуру, ее ширину и высоту, а также выходную текстуру. Входная текстура должна быть привязана к изображению текстуры GL_TEXTURE_2D (обычно это делается путем вызова функции glTexImage2D() ). Вы можете предоставить несколько уровней MIP-карт. Если выходная текстура не была привязана к изображению текстуры, она будет автоматически связана с эффектом как GL_TEXTURE_2D и с одним уровнем MIP-карты (0), который будет иметь тот же размер, что и входные данные.

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

Клиент удаленного управления

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

Чтобы включить клиентов удаленного управления для вашего медиаплеера, создайте RemoteControlClient с его конструктором, передав ему PendingIntent , который передает ACTION_MEDIA_BUTTON . Намерение также должно явно объявить в вашем приложении компонент BroadcastReceiver , который обрабатывает событие ACTION_MEDIA_BUTTON .

Чтобы объявить, какие входные данные управления мультимедиа может обрабатывать ваш проигрыватель, вы должны вызвать setTransportControlFlags() на вашем RemoteControlClient , передав набор флагов FLAG_KEY_MEDIA_* , таких как FLAG_KEY_MEDIA_PREVIOUS и FLAG_KEY_MEDIA_NEXT .

Затем вы должны зарегистрировать свой RemoteControlClient , передав его в MediaManager.registerRemoteControlClient() . После регистрации широковещательный приемник, который вы объявили при создании экземпляра RemoteControlClient будет получать события ACTION_MEDIA_BUTTON при нажатии кнопки на пульте дистанционного управления. Полученное вами намерение включает в себя KeyEvent для нажатой мультимедийной клавиши, которое вы можете получить из намерения с помощью getParcelableExtra(Intent.EXTRA_KEY_EVENT) .

Чтобы отобразить на пульте дистанционного управления информацию о воспроизведении мультимедиа, вызовите editMetaData() и добавьте метаданные в возвращенный RemoteControlClient.MetadataEditor . Вы можете предоставить растровое изображение для мультимедийного изображения, числовую информацию, например прошедшее время, и текстовую информацию, например название дорожки. Информацию о доступных ключах см. в флагах METADATA_KEY_* в MediaMetadataRetriever .

Пример реализации см. в разделе Random Music Player , который обеспечивает логику совместимости, позволяющую использовать клиент удаленного управления на устройствах Android 4.0, продолжая при этом поддерживать устройства обратно на Android 2.1.

Медиаплеер

  • Для потоковой передачи онлайн-медиа из MediaPlayer теперь требуется разрешение INTERNET . Если вы используете MediaPlayer для воспроизведения контента из Интернета, обязательно добавьте разрешение INTERNET в свой манифест, иначе воспроизведение мультимедиа не будет работать, начиная с Android 4.0.
  • setSurface() позволяет вам определить Surface , которая будет вести себя как приемник видео.
  • setDataSource() позволяет отправлять дополнительные HTTP-заголовки вместе с вашим запросом, что может быть полезно для потоковой передачи HTTP(S) в реальном времени.
  • Прямая трансляция HTTP(S) теперь учитывает файлы cookie HTTP во всех запросах.

Типы носителей

В Android 4.0 добавлена ​​поддержка:

  • Протокол потокового вещания HTTP/HTTPS версии 3
  • Кодирование звука ADTS raw AAC
  • WEBP-изображения
  • Матроска видео

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

Камера

Класс Camera теперь включает API для обнаружения лиц и управления зонами фокусировки и замера экспозиции.

Распознавание лиц

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

Чтобы обнаруживать лица в приложении камеры, вы должны зарегистрировать Camera.FaceDetectionListener , вызвав setFaceDetectionListener() . Затем вы можете запустить поверхность камеры и начать распознавать лица, вызвав startFaceDetection() .

Когда система обнаруживает одно или несколько лиц в сцене с камерой, она вызывает обратный вызов onFaceDetection() в вашей реализации Camera.FaceDetectionListener , включая массив объектов Camera.Face .

Экземпляр класса Camera.Face предоставляет различную информацию об обнаруженном лице, в том числе:

  • Rect , определяющий границы лица относительно текущего поля зрения камеры.
  • Целое число от 1 до 100, которое указывает, насколько система уверена в том, что объект является человеческим лицом.
  • Уникальный идентификатор, позволяющий отслеживать несколько лиц
  • Несколько Point объектов, указывающих, где расположены глаза и рот.

Примечание. Обнаружение лиц может не поддерживаться на некоторых устройствах, поэтому вам следует проверить это, вызвав getMaxNumDetectedFaces() , и убедиться, что возвращаемое значение больше нуля. Кроме того, некоторые устройства могут не поддерживать идентификацию глаз и рта, и в этом случае эти поля в объекте Camera.Face будут иметь значение null.

Зоны фокусировки и замера экспозиции

Приложения камеры теперь могут контролировать области, которые камера использует для фокусировки, а также для измерения баланса белого и автоматической экспозиции. Обе функции используют новый класс Camera.Area для указания области текущего обзора камеры, которая должна быть сфокусирована или замерена. Экземпляр класса Camera.Area определяет границы области с помощью Rect и вес области, представляющий уровень важности этой области по отношению к другим рассматриваемым областям, с помощью целого числа.

Прежде чем устанавливать зону фокусировки или зону измерения, вам следует сначала вызвать getMaxNumFocusAreas() или getMaxNumMeteringAreas() соответственно. Если они возвращают ноль, устройство не поддерживает соответствующую функцию.

Чтобы указать используемые области фокусировки или измерения, просто вызовите setFocusAreas() или setMeteringAreas() . Каждый из них имеет List объектов Camera.Area , которые указывают области, на которых следует выполнять фокусировку или замер. Например, вы можете реализовать функцию, которая позволяет пользователю устанавливать область фокусировки, касаясь области предварительного просмотра, которую вы затем преобразуете в объект Camera.Area и запрашиваете фокусировку камеры на этой области сцены. Фокус или экспозиция в этой области будет постоянно обновляться по мере изменения сцены в этой области.

Непрерывная автофокусировка для фотографий

Теперь вы можете включить непрерывную автофокусировку (CAF) при съемке фотографий. Чтобы включить CAF в приложении камеры, передайте FOCUS_MODE_CONTINUOUS_PICTURE в setFocusMode() . Когда будете готовы сделать снимок, вызовите autoFocus() . Ваш Camera.AutoFocusCallback немедленно получает обратный вызов, чтобы указать, была ли достигнута фокусировка. Чтобы возобновить CAF после получения обратного вызова, вы должны вызвать cancelAutoFocus() .

Примечание. Непрерывная автофокусировка также поддерживается при захвате видео с использованием FOCUS_MODE_CONTINUOUS_VIDEO , который был добавлен на уровне API 9.

Другие возможности камеры

  • Во время записи видео теперь вы можете вызвать takePicture() , чтобы сохранить фотографию, не прерывая видеосеанс. Прежде чем сделать это, вам следует вызвать isVideoSnapshotSupported() чтобы убедиться, что оборудование поддерживает эту функцию.
  • Теперь вы можете заблокировать автоматическую экспозицию и баланс белого с помощью setAutoExposureLock() и setAutoWhiteBalanceLock() чтобы предотвратить изменение этих свойств.
  • Теперь вы можете вызвать setDisplayOrientation() во время предварительного просмотра камеры. Раньше вы могли вызвать это только перед началом предварительного просмотра, но теперь вы можете изменить ориентацию в любое время.

Намерения трансляции камеры

  • Camera.ACTION_NEW_PICTURE : указывает, что пользователь сделал новую фотографию. Встроенное приложение «Камера» запускает эту трансляцию после съемки фотографии, а сторонние приложения камеры также должны транслировать это намерение после съемки фотографии.
  • Camera.ACTION_NEW_VIDEO : указывает, что пользователь снял новое видео. Встроенное приложение «Камера» запускает эту трансляцию после записи видео, а сторонние приложения камеры также должны транслировать это намерение после захвата видео.

Android Beam (NDEF Push с NFC)

Android Beam — это новая функция NFC, которая позволяет отправлять сообщения NDEF с одного устройства на другое (процесс, также известный как «NDEF Push»). Передача данных начинается, когда два устройства на базе Android, поддерживающие Android Beam, находятся в непосредственной близости. (около 4 см), обычно соприкасаясь спинами. Данные внутри сообщения NDEF могут содержать любые данные, которыми вы хотите поделиться между устройствами. Например, приложение «Люди» обменивается контактами, YouTube обменивается видео, а браузер передает URL-адреса с помощью Android Beam. .

Чтобы передавать данные между устройствами с помощью Android Beam, вам необходимо создать NdefMessage , содержащий информацию, которой вы хотите поделиться, пока ваша активность находится на переднем плане. Затем вы должны передать NdefMessage в систему одним из двух способов:

  • Определите одно NdefMessage для отправки во время действия:

    Вызовите setNdefPushMessage() в любое время, чтобы установить сообщение, которое вы хотите отправить. Например, вы можете вызвать этот метод и передать ему свое NdefMessage во время метода onCreate() вашей активности. Затем, когда Android Beam активируется на другом устройстве, когда действие находится на переднем плане, система отправляет NdefMessage на другое устройство.

  • Определите NdefMessage , который будет отправляться во время запуска Android Beam:

    Реализуйте NfcAdapter.CreateNdefMessageCallback , в котором ваша реализация метода createNdefMessage() возвращает NdefMessage который вы хотите отправить. Затем передайте реализацию NfcAdapter.CreateNdefMessageCallback в setNdefPushMessageCallback() .

    В этом случае, когда Android Beam активируется на другом устройстве, когда ваша активность находится на переднем плане, система вызывает createNdefMessage() , чтобы получить NdefMessage который вы хотите отправить. Это позволяет вам определить NdefMessage для доставки только после запуска Android Beam, если содержимое сообщения может меняться на протяжении всего срока действия.

Если вы хотите запустить какой-то конкретный код после того, как система успешно доставила ваше сообщение NDEF на другое устройство, вы можете реализовать NfcAdapter.OnNdefPushCompleteCallback и установить его с помощью setNdefPushCompleteCallback() . Затем система вызовет onNdefPushComplete() когда сообщение будет доставлено.

На принимающем устройстве система отправляет сообщения NDEF Push аналогично обычным тегам NFC. Система вызывает намерение с помощью действия ACTION_NDEF_DISCOVERED для запуска действия с URL-адресом или типом MIME, установленным в соответствии с первым NdefRecord в NdefMessage . Для действия, на которое вы хотите ответить, вы можете объявить фильтры намерений для URL-адресов или типов MIME, которые важны для вашего приложения. Дополнительную информацию о диспетчеризации тегов см. в руководстве разработчика NFC .

Если вы хотите, чтобы ваш NdefMessage содержал URI, теперь вы можете использовать удобный метод createUri для создания нового NdefRecord на основе строки или объекта Uri . Если URI представляет собой специальный формат, который вы хотите, чтобы ваше приложение также получало во время события Android Beam, вам следует создать фильтр намерений для своей деятельности, используя ту же схему URI, чтобы получать входящее сообщение NDEF.

Вам также следует передать «запись приложения Android» вместе с вашим NdefMessage , чтобы гарантировать, что ваше приложение обрабатывает входящее сообщение NDEF, даже если другие приложения фильтруют то же действие намерения. Вы можете создать запись приложения Android, вызвав createApplicationRecord() , передавая ему имя пакета вашего приложения. Когда другое устройство получает сообщение NDEF с записью приложения и несколько приложений содержат действия, которые обрабатывают указанное намерение, система всегда доставляет сообщение действию в вашем приложении (на основе соответствующей записи приложения). Если на целевом устройстве в настоящее время не установлено ваше приложение, система использует запись приложения Android для запуска Google Play и перенаправляет пользователя к приложению для его установки.

Если ваше приложение не использует API-интерфейсы NFC для отправки push-сообщений NDEF, Android обеспечивает поведение по умолчанию: когда ваше приложение находится на переднем плане на одном устройстве и Android Beam вызывается на другом устройстве под управлением Android, тогда другое устройство получает сообщение Сообщение NDEF с записью приложения Android, идентифицирующей ваше приложение. Если на принимающем устройстве установлено приложение, система его запускает; если оно не установлено, открывается Google Play и направляет пользователя к вашему приложению для его установки.

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

Wi-Fi P2P

Android теперь поддерживает одноранговые соединения Wi-Fi (P2P) между устройствами на базе Android и другими типами устройств (в соответствии с программой сертификации Wi-Fi Direct™ Wi -Fi Alliance) без точки доступа или подключения к Интернету. Платформа Android предоставляет набор API-интерфейсов Wi-Fi P2P, которые позволяют вам обнаруживать и подключаться к другим устройствам, когда каждое устройство поддерживает Wi-Fi P2P, а затем обмениваться данными через быстрое соединение на расстояниях, гораздо больших, чем соединение Bluetooth.

Новый пакет android.net.wifi.p2p содержит все API для выполнения одноранговых соединений с помощью Wi-Fi. Основной класс, с которым вам нужно работать, — это WifiP2pManager , который вы можете получить, вызвав getSystemService(WIFI_P2P_SERVICE) . WifiP2pManager включает API, которые позволяют вам:

  • Инициализируйте свое приложение для P2P-соединений, вызвав метод initialize()
  • Обнаружьте ближайшие устройства, вызвав discoverPeers()
  • Запустите P2P-соединение, вызвав метод connect()
  • И еще

Также необходимы несколько других интерфейсов и классов, например:

  • Интерфейс WifiP2pManager.ActionListener позволяет получать обратные вызовы, когда такая операция, как обнаружение одноранговых узлов или подключение к ним, завершается успешно или неудачно.
  • Интерфейс WifiP2pManager.PeerListListener позволяет получать информацию об обнаруженных пирах. Обратный вызов предоставляет WifiP2pDeviceList , из которого вы можете получить объект WifiP2pDevice для каждого устройства в пределах диапазона и получить такую ​​информацию, как имя устройства, адрес, тип устройства, конфигурации WPS, которые поддерживает устройство, и многое другое.
  • Интерфейс WifiP2pManager.GroupInfoListener позволяет получать информацию о P2P-группе. Обратный вызов предоставляет объект WifiP2pGroup , который предоставляет информацию о группе, такую ​​как владелец, имя сети и парольная фраза.
  • Интерфейс WifiP2pManager.ConnectionInfoListener позволяет получать информацию о текущем соединении. Обратный вызов предоставляет объект WifiP2pInfo , который содержит информацию о том, была ли сформирована группа и кто является ее владельцем.

Чтобы использовать API-интерфейсы Wi-Fi P2P, ваше приложение должно запросить следующие разрешения пользователя:

  • ACCESS_WIFI_STATE
  • CHANGE_WIFI_STATE
  • INTERNET (хотя ваше приложение технически не подключается к Интернету, для связи с узлами Wi-Fi P2P с помощью стандартных сокетов Java требуется разрешение Интернета).

Система Android также транслирует несколько различных действий во время определенных событий Wi-Fi P2P:

Дополнительную информацию см. в документации WifiP2pManager . Также ознакомьтесь с примером демонстрационного приложения Wi-Fi P2P .

Bluetooth-устройства здоровья

Android теперь поддерживает устройства Bluetooth Health Profile, поэтому вы можете создавать приложения, использующие Bluetooth для связи с медицинскими устройствами, поддерживающими Bluetooth, такими как пульсометры, измерители крови, термометры и весы.

Подобно обычным гарнитурам и устройствам с профилем A2DP, вам необходимо вызвать getProfileProxy() с BluetoothProfile.ServiceListener и типом профиля HEALTH , чтобы установить соединение с прокси-объектом профиля.

После получения прокси-сервера профиля здоровья (объекта BluetoothHealth ) для подключения и связи с сопряженными устройствами здравоохранения используются следующие новые классы Bluetooth:

  • BluetoothHealthCallback : необходимо расширить этот класс и реализовать методы обратного вызова, чтобы получать обновления об изменениях в состоянии регистрации приложения и состоянии канала Bluetooth.
  • BluetoothHealthAppConfiguration : во время обратных вызовов вашего BluetoothHealthCallback вы получите экземпляр этого объекта, который предоставляет информацию о конфигурации доступного устройства Bluetooth Health, которое вы должны использовать для выполнения различных операций, таких как инициирование и завершение соединений с API-интерфейсами BluetoothHealth .

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

Доступность

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

Режим исследования касанием

Пользователи с потерей зрения теперь могут исследовать экран, касаясь и перетаскивая палец по экрану, чтобы услышать голосовые описания контента. Поскольку режим исследования касанием работает как виртуальный курсор, он позволяет программам чтения с экрана идентифицировать описательный текст так же, как это делают программы чтения с экрана, когда пользователь перемещается с помощью d-pad или трекбола — путем чтения информации, предоставленной android:contentDescription и setContentDescription() при моделируемом событии «наведение». Итак, считайте, что это напоминание о том, что вам следует предоставлять описательный текст для представлений в вашем приложении, особенно для ImageButton , EditText , ImageView и других виджетов, которые естественным образом могут не содержать описательный текст.

Доступность для просмотров

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

Прежде всего важно отметить, что поведение метода sendAccessibilityEvent() изменилось в Android 4.0. Как и в предыдущей версии Android, когда пользователь включает службы специальных возможностей на устройстве и происходит событие ввода, такое как щелчок или наведение, соответствующее представление уведомляется с помощью вызова sendAccessibilityEvent() . Ранее реализация sendAccessibilityEvent() инициализировала AccessibilityEvent и отправляла его в AccessibilityManager . Новое поведение включает в себя некоторые дополнительные методы обратного вызова, которые позволяют представлению и его родителям добавлять к событию дополнительную контекстную информацию:

  1. При вызове методы sendAccessibilityEvent() и sendAccessibilityEventUnchecked() подчиняются onInitializeAccessibilityEvent() .

    Пользовательские реализации View могут захотеть реализовать onInitializeAccessibilityEvent() для прикрепления дополнительной информации о доступности к AccessibilityEvent , но также должны вызывать суперреализацию для предоставления информации по умолчанию, такой как стандартное описание контента, индекс элемента и т. д. Однако вам не следует добавлять дополнительный текстовый контент в этот обратный вызов — это произойдет дальше.

  2. Если после инициализации событие относится к одному из нескольких типов, которые должны быть заполнены текстовой информацией, представление затем получает вызов dispatchPopulateAccessibilityEvent() , который подчиняется обратному вызову onPopulateAccessibilityEvent() .

    Пользовательские реализации View обычно должны реализовывать onPopulateAccessibilityEvent() для добавления дополнительного текстового содержимого в AccessibilityEvent , если текст android:contentDescription отсутствует или недостаточен. Чтобы добавить дополнительное текстовое описание к AccessibilityEvent , вызовите getText() . add() .

  3. На этом этапе View передает событие вверх по иерархии просмотра, вызывая запросы requestSendAccessibilityEvent() в родительском представлении. Затем каждый родительский представление имеет возможность увеличить информацию о доступности, добавив AccessibilityRecord , пока в конечном итоге он не достигнет корневого представления, которое отправляет событие AccessibilityManager с sendAccessibilityEvent() .

В дополнение к новым методам выше, которые полезны при расширении класса View , вы также можете перехватить эти обратные вызовы событий в любом View , расширяя AccessibilityDelegate и установив его на представление с помощью setAccessibilityDelegate() . Когда вы это сделаете, каждый метод доступности в представлении определяет вызов в соответствующий метод в делегате. Например, когда представление получает вызов onPopulateAccessibilityEvent() , он передает его тому же методу в View.AccessibilityDelegate . Любые методы, не обработанные делегатом, возвращаются прямо к представлению для поведения по умолчанию. Это позволяет вам переопределить только методы, необходимые для любого данного представления, без расширения класса View .

Если вы хотите поддерживать совместимость с версиями Android до 4.0, а также поддерживаете новые API доступности, вы можете сделать это с последней версией библиотеки поддержки V4пакете совместимости, R4 ), используя набор классов утилиты, которые предоставляют Новые API-интерфейсы доступности в обратном совместном дизайне.

Услуги доступности

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

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

  1. Получив AccessibilityEvent из приложения, вызовите AccessibilityEvent.getRecord() AccessibilityRecord
  2. От AccessibilityEvent , либо отдельной AccessibilityRecord , вы можете вызвать getSource() , чтобы получить объект AccessibilityNodeInfo .

    AccessibilityNodeInfo представляет собой один узел содержимого окна в формате, который позволяет вам запросить информацию о доступности об этом узле. Объект AccessibilityNodeInfo , возвращаемый из AccessibilityEvent описывает источник события, тогда как источник из AccessibilityRecord описывает предшественника источника события.

  3. С помощью AccessibilityNodeInfo вы можете запросить информацию об этом, вызовать getParent() или getChild() чтобы пройти иерархию представления и даже добавить представления ребенка в узел.

Чтобы ваше приложение опубликовало себя в систему в качестве службы доступности, оно должно объявить файл конфигурации XML, который соответствует AccessibilityServiceInfo . Для получения дополнительной информации о создании службы доступности см. Включение AccessibilityService и SERVICE_META_DATA для получения информации о конфигурации XML.

Другие APIS доступности

Если вы заинтересованы в состоянии доступности устройства, у AccessibilityManager есть некоторые новые API, такие как:

Услуги проверки орфографии

Новая структура проверки орфографии позволяет приложениям создавать контролировщики орфографии способом, аналогичным структуре метода ввода (для IME). Чтобы создать новый контроль над орфографией, вы должны реализовать услугу, которая расширяет SpellCheckerService и расширяет класс SpellCheckerService.Session , чтобы предоставить предложения по орфографии на основе текста, предоставленного методами обратного вызова интерфейса. В методах обратного вызова SpellCheckerService.Session вы должны вернуть предложения по орфографии в качестве SuggestionsInfo объектов.

Приложения с службой проверки орфографии должны объявить разрешение BIND_TEXT_SERVICE в соответствии с требованиями службы. Служба также должна объявить фильтр намерений с <action android:name="android.service.textservice.SpellCheckerService" /> в качестве действия намерения и должен включать элемент <meta-data> , который объявляет информацию о конфигурации для проверки орфографии.

См. Пример приложения Service Shiper Checker и приложение Chem Skeeker Checter , например, код.

Текстовые двигатели

API-интерфейсы Text-To Speek (TTS) Android были значительно расширены, чтобы позволить приложениям более легко реализовать пользовательские двигатели TTS, в то время как приложения, которые хотят использовать двигатель TTS, имеют пару новых API для выбора двигателя.

Использование двигателей текста в речь

В предыдущих версиях Android вы можете использовать класс TextToSpeech для выполнения операций текста в речь (TTS) с использованием двигателя TTS, предоставленного системой, или установить пользовательский двигатель с использованием setEngineByPackageName() . В Android 4.0 метод setEngineByPackageName() был устарел, и теперь вы можете указать двигатель для использования с новым конструктором TextToSpeech , который принимает название пакета двигателя TTS.

Вы также можете запросить доступные двигатели TTS с getEngines() . Этот метод возвращает список объектов TextToSpeech.EngineInfo , которые включают метаданные, такие как значок, метка и название пакета двигателя.

Создание двигателей текста в речь

Ранее пользовательские двигатели требовали, чтобы двигатель был построен с использованием незарегистрированного файла заголовка. В Android 4.0 существует полный набор Framework API для строительства двигателей TTS.

Основная настройка требует реализации TextToSpeechService , которая отвечает на намерение INTENT_ACTION_TTS_SERVICE . Основная работа для двигателя TTS происходит во время обратного вызова onSynthesizeText() в сервисе, которая расширяет TextToSpeechService . Система доставляет этот метод два объекта:

  • SynthesisRequest : он содержит различные данные, включая текст для синтеза, локали, скорость речи и голосовой шаг.
  • SynthesisCallback : это интерфейс, посредством которого ваш двигатель TTS предоставляет полученные речевые данные в качестве потокового звука. Сначала двигатель должен вызовать start() чтобы указать, что двигатель готов доставить аудио, а затем вызовать audioAvailable() , передавая его аудиоданные в байтовом буфере. Как только ваш двигатель пройдет весь аудио через буфер, вызовите done() .

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

Для примера двигателя TTS с использованием новых API см. Приложение «Образец речевого двигателя» .

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

Android 4.0 дает пользователям точную видимость того, сколько сетевых данных используют их приложения. Приложение «Настройки» предоставляет элементы управления, которые позволяют пользователям управлять установленными ограничениями для использования сетевых данных и даже отключить использование фоновых данных для отдельных приложений. Чтобы пользователи не отключали доступ к данным вашего приложения из фона, вы должны разработать стратегии для эффективного использования подключения для передачи данных и корректировки использования в зависимости от типа доступного соединения.

Если ваше приложение выполняет много сетевых транзакций, вы должны предоставить пользовательские настройки, которые позволяют пользователям управлять привычками данных вашего приложения, например, как часто ваше приложение синхронизирует данные, независимо от того, выполняют ли загрузки/загрузки только при Wi-Fi, используется ли использование. Данные во время роуминга и т. Д. С этими элементами управления, доступными для них, пользователи гораздо реже отключат доступ вашего приложения к данным, когда они приближаются к своим ограничениям, потому что вместо этого они могут точно контролировать, сколько данных использует ваше приложение. Если вы предоставите предварительную деятельность с этими настройками, вы должны включить в его манифест -объявление фильтр намерения для действия ACTION_MANAGE_NETWORK_USAGE . Например:

<activity android:name="DataPreferences" android:label="@string/title_preferences">
    <intent-filter>
       <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
       <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

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

Также будьте осторожны с тем, что getBackgroundDataSetting() теперь устарел и всегда возвращает истинную - используйте getActiveNetworkInfo() вместо этого. Прежде чем вы пытаетесь выполнить какие -либо сетевые транзакции, вы всегда должны вызывать getActiveNetworkInfo() , чтобы получить NetworkInfo , которая представляет текущую сеть и Query isConnected() , чтобы проверить, имеет ли устройство соединение. Затем вы можете проверить другие свойства подключения, например, бродит ли устройство или подключено к Wi-Fi.

Предприятие

Android 4.0 расширяет возможности для корпоративного приложения со следующими функциями.

VPN Services

Новый VpnService позволяет приложениям создавать свой собственный VPN (виртуальная частная сеть), работающая в качестве Service . Служба VPN создает интерфейс для виртуальной сети со своим собственным адресом и правилами маршрутизации и выполняет все чтение и запись с помощью дескриптора файла.

Чтобы создать службу VPN, используйте VpnService.Builder , который позволяет указать сетевой адрес, DNS -сервер, сетевой маршрут и многое другое. При завершении вы можете установить интерфейс, позвонив establish() , который возвращает ParcelFileDescriptor .

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

Политики устройства

Приложения, которые управляют ограничениями устройства, теперь могут отключить камеру с помощью setCameraDisabled() и свойства USES_POLICY_DISABLE_CAMERA (применяется с элементом <disable-camera /> в файле конфигурации политики).

Управление сертификатами

Новый класс KeyChain предоставляет API, которые позволяют вам импортировать и доступа к сертификатам в магазине системных ключей. Сертификаты оптимизируют установку обоих клиентских сертификатов (для проверки личности пользователя) и сертификатов авторитета сертификатов (для проверки идентификации сервера). Приложения, такие как веб -браузеры или почтовые клиенты, могут получить доступ к установленным сертификатам для аутентификации пользователей на серверах. Смотрите документацию KeyChain для получения дополнительной информации.

Датчики устройства

Два новых типа датчиков были добавлены в Android 4.0:

  • TYPE_AMBIENT_TEMPERATURE : датчик температуры, который обеспечивает окружающую (комнату) температуру в градусах по Цельсию.
  • TYPE_RELATIVE_HUMIDITY : датчик влажности, который обеспечивает относительную влажность окружающей среды (комната) в процентах.

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

Предыдущий датчик температуры, TYPE_TEMPERATURE , устарел. Вместо этого вы должны использовать датчик TYPE_AMBIENT_TEMPERATURE .

Кроме того, три синтетических датчика Android были значительно улучшены, так что теперь они имеют более низкую задержку и более плавную выход. Эти датчики включают датчик гравитации ( TYPE_GRAVITY ), векторный датчик вращения ( TYPE_ROTATION_VECTOR ) и датчик линейного ускорения ( TYPE_LINEAR_ACCELERATION ). Улучшенные датчики полагаются на датчик гироскопа, чтобы улучшить их выход, поэтому датчики появляются только на устройствах, которые имеют гироскоп.

Панель действий

ActionBar был обновлен, чтобы поддержать несколько новых поведений. Самое главное, что система изящно управляет размером и конфигурацией панели действий при запуске на небольших экранах, чтобы обеспечить оптимальный пользовательский опыт на всех размерах экрана. Например, когда экран является узким (например, когда телефон в ориентации на портрету), навигационные вкладки панели действий появляются в «сложенной панели», которая появляется непосредственно под основной панелью действий. Вы также можете выбрать «Сплит -панель действий», которая помещает все элементы действий в отдельную полосу в нижней части экрана, когда экран узкий.

Сплит -боевой панель

Если ваша панель действий включает в себя несколько элементов действия, не все из них вписываются в панель действий на узком экране, поэтому система поместит их в меню переполнения. Тем не менее, Android 4.0 позволяет вам включить «сплит -панель действий», чтобы на экране можно было появиться больше элементов действий в отдельной панели внизу экрана. Чтобы включить сплит -панель действий, добавить android:uiOptions с "splitActionBarWhenNarrow" Ваш тег <application> или индивидуальные <activity> теги в вашем манифестном файле. действие).

Если вы хотите использовать навигационные вкладки, предоставленные APIS ActionBar.Tab , но не нужна основная панель действий сверху (вы хотите, чтобы только вкладки появились сверх Также вызовите setDisplayShowHomeEnabled(false) , чтобы отключить значок приложения в строке действий. Ничего не осталось в основной панели действий, он исчезает - все осталось, это навигационные вкладки вверху и элементы действия внизу экрана.

Боевые стили

Если вы хотите применить пользовательский стиль к панели действий, вы можете использовать свойства нового стиля, а также backgroundStacked backgroundSplit чтобы применить фон, подлежащий рисованию или цвет, к сложенной полосе и разделенной панели соответственно. Вы также можете установить эти стили во время выполнения с помощью setStackedBackgroundDrawable() и setSplitBackgroundDrawable() .

Поставщик действий

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

Например, ShareActionProvider -это расширение ActionProvider , которое облегчает действие «общего» из строки действий. Вместо использования традиционного элемента действия, который вызывает намерение ACTION_SEND , вы можете использовать этот поставщик действий для представления представления действия с выпаданием. Список приложений, которые ShareActionProvider намерение ACTION_SEND .

Чтобы объявить поставщика действий для элемента действия, включите атрибут android:actionProviderClass в элемент <item> для меню «Параметры вашей деятельности» с именем класса поставщика действий в качестве значения. Например:

<item android:id="@+id/menu_share"
      android:title="Share"
      android:showAsAction="ifRoom"
      android:actionProviderClass="android.widget.ShareActionProvider" />

В методе onCreateOptionsMenu() вызов обратного вызова () извлеките экземпляр поставщика действий из пункта меню и установите намерение:

Котлин

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options, menu)
    val shareActionProvider = menu.findItem(R.id.menu_share)?.actionProvider as? ShareActionProvider
    // Set the share intent of the share action provider.
    shareActionProvider?.setShareIntent(createShareIntent())
    ...
    return super.onCreateOptionsMenu(menu)
}

Ява

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.options, menu);
    ShareActionProvider shareActionProvider =
          (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();
    // Set the share intent of the share action provider.
    shareActionProvider.setShareIntent(createShareIntent());
    ...
    return super.onCreateOptionsMenu(menu);
}

Для примера с использованием ShareActionProvider см .

Складные взгляды действий

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

Чтобы заявить, что элемент действия, который содержит представление действия, может быть складным, включите флаг “collapseActionView" в атрибуте android:showAsAction для элемента <item> в файле XML меню.

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

Чтобы управлять складным представлением действия, вы можете вызвать collapseActionView() и expandActionView() на соответствующем MenuItem .

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

Другие API для боевой панели

  • setHomeButtonEnabled() позволяет вам указать, ведет ли значок/логотип как кнопку для навигации домой или «вверх» (пройти «true», чтобы он был в качестве кнопки).
  • setIcon() и setLogo() позволяет вам определить значок стержня или логотип действий во время выполнения.
  • Fragment.setMenuVisibility() позволяет вам включить или отключить видимость пунктов меню «Параметры», объявленных фрагментом. Это полезно, если фрагмент был добавлен в деятельность, но не видно, поэтому пункты меню должны быть скрыты.
  • FragmentManager.invalidateOptionsMenu() позволяет недействительно меню «Параметры деятельности» во время различных состояний жизненного цикла фрагмента, в котором может быть недоступен использование эквивалентного метода от Activity .

Пользовательский интерфейс и представления

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

Gridlayout

GridLayout - это новая группа View, которая помещает детей в прямоугольную сетку. В отличие от TableLayout , GridLayout опирается на плоскую иерархию и не использует промежуточные представления, такие как табличные строки для обеспечения структуры. Вместо этого дети указывают, какие строки (ы) и столбцы они должны занимать (ячейки могут охватывать несколько строк и/или столбцов), и по умолчанию выложены последовательно через ряды и столбцы сетки. Ориентация GridLayout определяет, являются ли последовательные дети по умолчанию выложены горизонтально или вертикально. Пространство между детьми может быть указано либо с использованием экземпляров нового просмотра Space , либо путем установки соответствующих параметров маржи для детей.

См. Apidemos для образцов с использованием GridLayout .

TextureView

TextureView - это новое представление, которое позволяет отображать поток контента, такой как видео или сцена OpenGL. Несмотря на то, что TextureView аналогично SurfaceView , он уникален тем, что он ведет себя как обычный вид, а не создает отдельное окно, поэтому вы можете относиться к нему как к любому другому объекту View . Например, вы можете применить преобразования, оживить их с помощью ViewPropertyAnimator или отрегулировать его непрозрачность с помощью setAlpha() .

Остерегайтесь, что TextureView работает только в аппаратном ускоренном окне.

Для получения дополнительной информации см. Документацию TextureView .

Переключить виджет

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

Вы можете использовать атрибуты android:textOn и android:textOff чтобы указать текст, чтобы отображаться на коммутаторе при включении и выключении. Атрибут android:text также позволяет разместить этикетку рядом с переключателем.

Для примера с использованием коммутаторов см. Файл макета Switches.xml и соответствующую активность коммутаторов .

Android 3.0 представила PopupMenu для создания коротких контекстуальных меню, которые появляются в якорной точке, которую вы указываете (обычно в точке выбранного элемента). Android 4.0 расширяет PopupMenu с несколькими полезными функциями:

  • Теперь вы можете легко раздуть содержимое всплывающего меню из ресурса меню XML с inflate() , передавая его идентификатор ресурса меню.
  • Теперь вы также можете создать PopupMenu.OnDismissListener , который получает обратный вызов, когда меню уволено.

Предпочтения

Новый абстрактный класс TwoStatePreference служит основой для предпочтений, которые предоставляют вариант выбора из двух штатов. Новый SwitchPreference - это расширение TwoStatePreference , которое предоставляет виджет Switch в представлении предпочтения, чтобы пользователи могли включать или выключить настройку без необходимости открыть дополнительный экран или диалог. Например, в приложении «Настройки» используется SwitchPreference для настройки Wi-Fi и Bluetooth.

Системные темы

Тема по умолчанию для всех приложений, которые нацелены на Android 4.0 (устанавливая либо targetSdkVersion , либо minSdkVersion в “14" или выше), теперь является темой «Устройство по умолчанию»: Theme.DeviceDefault . Это может быть темная тема или другая темная тема. конкретным устройством.

Theme.Holo Семейство тем гарантированно не перейдет с одного устройства на другое при запуске одной и той же версии Android. Если вы явно применяете какую -либо из Theme.Holo

Если вы хотите, чтобы ваше приложение смешивалось с общей темой устройства (например, когда различные OEM -производители предоставляют различные темы по умолчанию для системы), вы должны явно применять темы из семейства Theme.DeviceDefault .

Кнопка меню «Параметры»

Начиная с Android 4.0, вы заметите, что телефоны больше не требуется аппаратная кнопка меню. Тем не менее, вам не нужно беспокоиться об этом, если ваше существующее приложение предоставит меню «Параметры» и ожидает, что будет кнопка меню. Чтобы гарантировать, что существующие приложения продолжают работать так, как они ожидают, система предоставляет кнопку меню на экране для приложений, которые были разработаны для старых версий Android.

Для наилучшего пользовательского опыта, новые и обновленные приложения должны вместо этого использовать The ActionBar для предоставления доступа к элементам меню и установить targetSdkVersion "14" чтобы воспользоваться преимуществами последнего поведения Framework по умолчанию.

Управление для видимости системного пользовательского интерфейса

С первых дней Android система управляла компонентом пользовательского интерфейса, известного как строка состояния , которая находится в верхней части устройств телефона для предоставления информации, такой как сигнал носителя, время, уведомления и так далее. Android 3.0 добавил системную панель для планшетных устройств, которая находится в нижней части экрана, чтобы предоставить системную навигационную навигационную контроль (дома, назад и т. Д.), А также интерфейс для элементов, традиционно предоставляемых строкой состояния. В Android 4.0 система предоставляет новый тип системы системного пользовательского интерфейса, который называется навигационной панелью . Вы можете считать навигационную панель повторной настройкой версии системной панели, предназначенной для мобильных телефонов-она предоставляет элементы управления навигацией для устройств, которые не имеют аппаратных аналогов для навигации по системе, но она оставляет пользовательский интерфейс уведомления системной панели и устанавливает элементы управления. Таким образом, устройство, которое обеспечивает навигационную панель, также имеет панель состояния вверху.

По сей день вы можете скрыть строку состояния на телефонах, используя флаг FLAG_FULLSCREEN . В Android 4.0 API, которые контролируют видимость системы системного панели, были обновлены, чтобы лучше отражать поведение как панели системы, так и навигационной панели:

  • Флаг SYSTEM_UI_FLAG_LOW_PROFILE заменяет флаг STATUS_BAR_HIDDEN . При установке этот флаг включает в себя режим «Низкопрофильный» для системной панели или навигационной панели. Кнопки навигации DIM и другие элементы в панели системы также скрывают.
  • Флаг SYSTEM_UI_FLAG_VISIBLE заменяет флаг STATUS_BAR_VISIBLE , чтобы запросить системную панель или навигационную панель.
  • SYSTEM_UI_FLAG_HIDE_NAVIGATION - это новый флаг, который запрашивает навигационную панель полностью скрыть. Имейте в виду, что это работает только для навигационной панели , используемой некоторыми телефонами (она не скрывает системную панель на планшетах). Навигационная строка возвращается для просмотра, как только система получает пользовательский ввод. Таким образом, этот режим полезен главным образом для воспроизведения видео или других случаев, в которых необходим весь экран, но пользовательский ввод не требуется.

Вы можете установить каждый из этих флагов для панели системной панели и навигационной панели, позвонив в setSystemUiVisibility() в любом представлении в вашей деятельности. Диспетчер Window объединяет (или в Togethesh) все флаги из всех видов в вашем окне и применяют их к пользовательскому интерфейсу System, если ваше окно имеет фокус ввода. Когда ваше окно теряет фокус ввода (пользователь отступает от вашего приложения или появляется диалог), ваши флаги перестают вступать в силу. Точно так же, если вы удалите эти представления из иерархии представления, их флаги больше не применяются.

Чтобы синхронизировать другие события в вашей деятельности с изменениями видимости в системном пользовательском интерфейсе (например, скрыть строку действий или другие элементы управления пользовательским интерфейсом, когда в системе пользовательский интерфейс скрывается), вы должны зарегистрировать View.OnSystemUiVisibilityChangeListener AnsystemuivisibilityChangeListener уведомляется, когда нагля к видимости системы системы. или навигационная планка изменяется.

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

Входная структура

Android 4.0 добавляет поддержку событий курсора и событий стилуса и кнопок мыши.

Наветренные события

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

Чтобы получить события Hover в представлении, реализуйте View.OnHoverListener и зарегистрируйте его в setOnHoverListener() . Когда на просмотре происходит событие Hover, ваш слушатель получает вызов onHover() , предоставляя View , которое получило событие, и MotionEvent , которое описывает тип происходящего события. Событие Hover может быть одним из следующих:

Ваша View.OnHoverListener должен вернуть True из onHover() , если он обрабатывает событие Hover. Если ваш слушатель возвращает false, то событие Hover будет отправлено в родительский представление, как обычно.

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

Для демонстрации новых событий Hover см. В классе Hover в Apidemos.

Стайлус и мышь кнопки события

Теперь Android предоставляет API для получения ввода от устройства ввода стилуса, такого как периферийное устройство для планшета Digitizer или сенсорный экран с поддержкой стилуса.

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

Ваше приложение может различать ввод пальцев, мыши, стилуса и ластика, запрашивая «Тип инструмента», связанный с каждым указателем в MotionEvent используя getToolType() . В настоящее время типы инструментов, определенных в данный момент: TOOL_TYPE_UNKNOWN , TOOL_TYPE_FINGER , TOOL_TYPE_MOUSE , TOOL_TYPE_STYLUS и TOOL_TYPE_ERASER . Запротив типа инструмента, ваше приложение может выбрать ввод стилуса различными способами от ввода пальцев или мыши.

Ваше приложение также может запрашивать, какие кнопки мыши или стилуса нажимают, запрашивая «состояние кнопки» MotionEvent с использованием getButtonState() . В настоящее время состояния, определенные в данный момент: BUTTON_PRIMARY , BUTTON_SECONDARY , BUTTON_TERTIARY , BUTTON_BACK и BUTTON_FORWARD . и кнопки «Переходные мыши» автоматически нанесены на карту с ключами KEYCODE_BACK и KEYCODE_FORWARD .

В дополнение к точному измерению положения и давления контакта, некоторые устройства ввода стилуса также сообщают о расстоянии между наконечником стилуса и дигитализатором, углом наклона стилуса и углом ориентации стилуса. Ваше приложение может запросить эту информацию, используя getAxisValue() с помощью кодов оси AXIS_DISTANCE , AXIS_TILT и AXIS_ORIENTATION .

Для демонстрации типов инструментов, состояний кнопок и новых кодов оси см. В классе Touchpaint в апидеме.

Характеристики

Новый класс Property обеспечивает быстрый, эффективный и простой способ указать свойство на любом объекте, который позволяет вызывающим абонентам генерировать/получать значения на целевые объекты. Это также позволяет функциональности передавать ссылки на поле/метод и позволяет коду устанавливать/получать значения свойства, не зная подробностей о том, каковы поля/методы.

Например, если вы хотите установить значение bar на объекте foo , вы ранее сделали это:

Котлин

foo.bar = value

Ява

foo.bar = value;

Если вы хотите позвонить сеттеру для базового личного полевого bar , вы ранее сделали это:

Котлин

foo.setBar(value)

Ява

foo.setBar(value);

Однако, если вы хотите передать экземпляр foo и иметь какой -то другой код, установите значение bar , на самом деле нет способа сделать это до Android 4.0.

Используя класс Property , вы можете объявить BAR объекта Property в классе Foo , чтобы вы могли установить поле на экземпляре foo of Class Foo , как это:

Котлин

BAR.set(foo, value)

Ява

BAR.set(foo, value);

Класс View теперь использует класс Property , чтобы позволить вам устанавливать различные поля, такие как свойства преобразования, которые были добавлены в Android 3.0 ( ROTATION , ROTATION_X , TRANSLATION_X и т. Д.).

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

Аппаратное ускорение

Начиная с Android 4.0, аппаратное ускорение для всех Windows включено по умолчанию, если ваше приложение установило либо targetSdkVersion , либо minSdkVersion “14" или выше. Ускорение аппаратного обеспечения обычно приводит к более плавной анимации, более плавной прокрутке и общей производительности и отклике на взаимодействие с пользователем .

При необходимости вы можете вручную отключить аппаратное ускорение с помощью атрибута hardwareAccelerated для индивидуальных элементов <activity> или элемента <application> . В качестве альтернативы вы можете отключить аппаратное ускорение для отдельных представлений, вызывая setLayerType(LAYER_TYPE_SOFTWARE) .

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

JNI меняется

В предыдущих версиях Android JNI локальные ссылки не были косвенными ручками; Android использовал прямые указатели. Это не была проблемой, если коллекционер мусора не перемещал объекты, но, казалось, сработала, потому что это позволило писать код багги. В Android 4.0 система теперь использует косвенные ссылки, чтобы обнаружить эти ошибки.

Входы и выходы местных ссылок JNI описаны в «локальных и глобальных ссылках» в советах JNI . В Android 4.0 CheckJNI был улучшен для обнаружения этих ошибок. Посмотрите блог Android Developers для предстоящего поста об общих ошибках с ссылками JNI и ссылками и ссылками на JNI и ссылками на JNI и ссылками на JNI и ссылками на JNI и ссылками на JNI и ссылками на JNI и ссылки на JNI и ссылки и JNI и ссылки и ссылки на JNI. Как вы можете их исправить.

Это изменение в реализации JNI влияет только на приложения, которые нацелены на Android 4.0, устанавливая либо targetSdkVersion , либо minSdkVersion “14" или выше. Если вы установили эти атрибуты на любое более низкое значение, то локальные ссылки JNI ведут себя так же, как и в предыдущих версиях. .

Вебкит

  • Webkit обновлен до версии 534.30
  • Поддержка Indic Fonts (Devanagari, Bengali и Tamil, включая сложную поддержку символов, необходимую для объединения глифов) в WebView и встроенном браузере
  • Поддержка эфиопических, грузинских и армянских шрифтов в WebView и встроенного браузера
  • Поддержка WebDriver облегчает тестирование приложений, которые используют WebView

Android-браузер

Приложение браузера добавляет следующие функции для поддержки веб-приложений:

Разрешения

The following are new permissions:

Device Features

The following are new device features:

  • FEATURE_WIFI_DIRECT : Declares that the application uses Wi-Fi for peer-to-peer communications.

For a detailed view of all API changes in Android 4.0 (API Level 14), see the API Differences Report .

Previous APIs

In addition to everything above, Android 4.0 naturally supports all APIs from previous releases. Because the Android 3.x platform is available only for large-screen devices, if you've been developing primarily for handsets, then you might not be aware of all the APIs added to Android in these recent releases.

Here's a look at some of the most notable APIs you might have missed that are now available on handsets as well:

Android 3.0
  • Fragment : A framework component that allows you to separate distinct elements of an activity into self-contained modules that define their own UI and lifecycle. See the Fragments developer guide.
  • ActionBar : A replacement for the traditional title bar at the top of the activity window. It includes the application logo in the left corner and provides a new interface for menu items. See the Action Bar developer guide.
  • Loader : A framework component that facilitates asynchronous loading of data in combination with UI components to dynamically load data without blocking the main thread. See the Loaders developer guide.
  • System clipboard: Applications can copy and paste data (beyond mere text) to and from the system-wide clipboard. Clipped data can be plain text, a URI, or an intent. See the Copy and Paste developer guide.
  • Drag and drop: A set of APIs built into the view framework that facilitates drag and drop operations. See the Drag and Drop developer guide.
  • An all new flexible animation framework allows you to animate arbitrary properties of any object (View, Drawable, Fragment, Object, or anything else) and define animation aspects such as duration, interpolation, repeat and more. The new framework makes Animations in Android simpler than ever. See the Property Animation developer guide.
  • RenderScript graphics and compute engine: RenderScript offers a high performance 3D graphics rendering and compute API at the native level, which you write in the C (C99 standard), providing the type of performance you expect from a native environment while remaining portable across various CPUs and GPUs. See the RenderScript developer guide.
  • Hardware accelerated 2D graphics: You can now enable the OpenGL renderer for your application by setting {android:hardwareAccelerated="true"} in your manifest element's <application> element or for individual <activity> elements. Это приводит к более плавной анимации, более плавной прокрутке и общему повышению производительности и реакции на взаимодействие с пользователем.

    Note: If you set your application's minSdkVersion or targetSdkVersion to "14" or higher, hardware acceleration is enabled by default.

  • And much, much more. See the Android 3.0 Platform notes for more information.
Android 3.1
  • USB APIs: Powerful new APIs for integrating connected peripherals with Android applications. The APIs are based on a USB stack and services that are built into the platform, including support for both USB host and device interactions. See the USB Host and Accessory developer guide.
  • MTP/PTP APIs: Applications can interact directly with connected cameras and other PTP devices to receive notifications when devices are attached and removed, manage files and storage on those devices, and transfer files and metadata to and from them. The MTP API implements the PTP (Picture Transfer Protocol) subset of the MTP (Media Transfer Protocol) specification. See the android.mtp documentation.
  • RTP APIs: Android exposes an API to its built-in RTP (Real-time Transport Protocol) stack, which applications can use to manage on-demand or interactive data streaming. In particular, apps that provide VOIP, push-to-talk, conferencing, and audio streaming can use the API to initiate sessions and transmit or receive data streams over any available network. See the android.net.rtp documentation.
  • Support for joysticks and other generic motion inputs.
  • See the Android 3.1 Platform notes for many more new APIs.
Android 3.2
  • New screens support APIs that give you more control over how your applications are displayed across different screen sizes. The API extends the existing screen support model with the ability to precisely target specific screen size ranges by dimensions, measured in density-independent pixel units (such as 600dp or 720dp wide), rather than by their generalized screen sizes (such as large or xlarge ). For example, this is important in order to help you distinguish between a 5" device and a 7" device, which would both traditionally be bucketed as "large" screens. See the blog post, New Tools for Managing Screen Sizes .
  • New constants for <uses-feature> to declare landscape or portrait screen orientation requirements.
  • The device "screen size" configuration now changes during a screen orientation change. If your app targets API level 13 or higher, you must handle the "screenSize" configuration change if you also want to handle the "orientation" configuration change. See android:configChanges for more information.
  • See the Android 3.2 Platform notes for other new APIs.

API Уровень

The Android 4.0 API is assigned an integer identifier— 14 —that is stored in the system itself. This identifier, called the "API level", allows the system to correctly determine whether an application is compatible with the system, prior to installing the application.

To use APIs introduced in Android 4.0 in your application, you need compile the application against an Android platform that supports API level 14 or higher. Depending on your needs, you might also need to add an android:minSdkVersion="14" attribute to the <uses-sdk> element.

Для получения дополнительной информации прочитайте, что такое уровень API?