В Android 16 представлен модуль Ranging, который обеспечивает единый и стандартизированный интерфейс для точного измерения расстояния между устройствами. Вы можете использовать этот API для измерения расстояния и положения соседних устройств, не обрабатывая каждую технологию измерения расстояния отдельно.
Модуль определения дальности поддерживает следующие технологии:
- Сверхширокополосный
- Звук канала Bluetooth
- Wi-Fi NAN RTT
- Диапазон RSSI Bluetooth
Диапазон возможностей и доступности
Класс RangingManager предоставляет приложениям информацию о поддерживаемых локальным устройством технологиях измерения расстояния, а также о доступности и возможностях каждой технологии. Приложения могут зарегистрироваться для получения Callback для получения обновлений о любых изменениях в доступности или возможностях поддерживаемых технологий.
роли устройств
Устройство, участвующее в сеансе измерения расстояния, должно быть либо инициатором , либо ответчиком . Устройство-инициатор начинает сеанс измерения расстояния с одним или несколькими устройствами-ответчиками. Устройство-ответчик отвечает на запросы измерения расстояния только от одного инициатора одновременно. Роль для данного устройства в сеансе измерения расстояния можно указать с помощью класса RangingPreference .
Типы сеансов измерения расстояний
При начале сеанса измерения расстояния между устройствами часто необходимо установить внеполосную передачу данных для обмена параметрами в рамках сеанса.
Модуль Ranging может обрабатывать стандартные согласования (OOB-согласования) за вас, но он также поддерживает пользовательские реализации OOB-согласований.

Реализация по умолчанию (OOB)
В этом типе сессии ( RANGING_SESSION_OOB ) модуль определения расстояния обрабатывает внеполосные согласования для начала сессии определения расстояния. Он выбирает подходящие параметры на основе предпочтений определения расстояния, предоставленных приложением, и использует соответствующие технологии в зависимости от того, что поддерживают оба устройства. Этот тип сессии использует стандартизированную OOB specification .
Модуль определения дальности (Ranging) определяет только формат и последовательность исходящих данных, используемых для взаимодействия с соседним устройством. Он не занимается обнаружением соседних устройств или установлением соединения.
Пользовательская реализация "из коробки"
В этом типе сессии ( RANGING_SESSION_RAW ) приложение обходит стандартный поток обработки данных модуля определения расстояния и обрабатывает собственные параметры и согласование параметров. Это означает, что приложение должно определить, какие технологии поддерживает устройство-партнер, согласовать параметры определения расстояния и начать сессию определения расстояния.
Диапазон предпочтений
Для указания параметров, выбранных для сеанса измерения расстояния, используйте объект RangingPreference . К ним относятся следующие:
- Роль устройства. Это указывает, будет ли устройство инициатором или ответчиком.
- Настройка измерения расстояний. Объект
RangingConfigопределяет тип сеанса измерения расстояний и другие параметры, необходимые для начала сеанса. - Конфигурация сессии. Объект
SessionConfigзадает параметры, которые должны применяться к сессии измерения расстояния, такие как ограничение на количество измерений, объединение данных с датчиков, конфигурация геозоны и многое другое.
Разрешение на вырубку леса
Для доступа ко всем существующим и будущим технологиям определения расстояния модулю Ranging требуется новое унифицированное разрешение ( android.permission.RANGING ). Это разрешение находится в списке NEARBY_DEVICES_PERMISSIONS .
<uses-permission android:name="android.permission.RANGING" />
Ограничения и лимиты
Модуль определения дальности может ограничивать дальность действия по нескольким причинам, в том числе по следующим:
- Сторонним приложениям разрешено выполнять измерение расстояния в фоновом режиме только с использованием сверхширокополосной связи и только на поддерживаемых устройствах . Измерение расстояния в фоновом режиме с использованием других технологий не допускается.
- Измерение расстояния не допускается, если достигнуто максимальное количество одновременных сеансов измерения расстояния устройством.
- Дальность действия может быть ограничена из-за проблем со здоровьем системы, таких как состояние батареи, производительность или память.
Модуль определения дальности также имеет следующие известные ограничения:
- Модуль определения дальности поддерживает передачу данных о дальности только на соседние устройства для сверхширокополосной связи. Для других технологий модуль определения дальности передает данные только на инициирующее устройство.
- Модуль измерения расстояния поддерживает динамическое добавление устройств только в режиме измерения расстояния без привязки к конкретному устройству и только для сверхширокополосной связи.
- Модуль Ranging не поддерживает сеансы сверхширокополосной связи «один ко многим» для стандартных реализаций OOB . Если вы передадите несколько дескрипторов устройств, модуль создаст сеанс «один к одному» для каждого устройства-партнера, поддерживающего сверхширокополосную связь.
Проведите замеры расстояния.
Для проведения измерения расстояния с помощью модуля «Измерение расстояния» выполните следующие шаги:
- Убедитесь, что все устройства работают под управлением Android 16 или более поздней версии.
- Укажите разрешение
android.permission.RANGINGв манифесте приложения. - Оцените возможности и доступность технологий определения расстояния.
- Найдите аналогичное устройство для проведения измерений.
- Установите соединение для внеполосного обмена данными, используя один из типов сеансов, описанных в разделе «Типы сеансов определения дальности» .
- Инициируйте измерение расстояния и непрерывно собирайте данные о расстоянии.
- Завершить сеанс измерения расстояний.
Приведенный ниже пример кода демонстрирует эти шаги как для роли инициатора, так и для роли ответчика.
Котлин
class RangingApp {
// Starts a ranging session on the initiator side.
fun startRangingInitiator(
context: Context,
deviceHandle: DeviceHandle,
executor: Executor,
callback: RangingSessionCallback
) {
// Get the RangingManager which is the entry point for ranging module.
val manager = context.getSystemService(RangingManager::class.java)
// Create a new RangingSession using the provided executor and callback.
val session = manager.createRangingSession(executor, callback)
// Create an OobInitiatorRangingConfig, which specifies the ranging parameters for
// the initiator role.
val config = OobInitiatorRangingConfig.Builder()
.setFastestRangingInterval(Duration.ofMillis(100))
.setSlowestRangingInterval(Duration.ofMillis(5000))
.setRangingMode(RANGING_MODE_AUTO)
.setSecurityLevel(SECURITY_LEVEL_BASIC)
.addDeviceHandle(deviceHandle)
.build()
// Create a RangingPreference, which specifies the role (initiator) and
// configuration for the ranging session.
val preference =
RangingPreference.Builder(DEVICE_ROLE_INITIATOR, config).build()
// Start ranging session.
session.start(preference)
// If successful, the ranging data will be sent through callback#onResults
// Stop ranging session
session.stop()
}
// Starts a ranging session on the responder side.
fun startRangingResponder(
context: Context,
deviceHandle: DeviceHandle,
executor: Executor,
callback: RangingSessionCallback
) {
// Get the RangingManager which is the entry point for ranging module.
val manager = context.getSystemService(RangingManager::class.java)
// Create a new RangingSession using the provided executor and callback.
val session = manager.createRangingSession(executor, callback)
// Create an OobResponderRangingConfig, which specifies the ranging parameters for
// the responder role.
val config = OobResponderRangingConfig.Builder(deviceHandle).build()
// Create a RangingPreference, which specifies the role (responder) and
// configuration for the ranging session.
val preference =
RangingPreference.Builder(DEVICE_ROLE_RESPONDER, config).build()
// Start the ranging session.
session.start(preference)
// Stop the ranging session
session.stop()
}
}
Java
public class RangingApp {
// Starts a ranging session on the initiator side.
void startRangingInitiator(Context context, DeviceHandle deviceHandle, Executor executor, RangingSessionCallback callback) {
// Get the RangingManager which is the entry point for ranging module.
RangingManager manager = context.getSystemService(RangingManager.class);
// Create a new RangingSession using the provided executor and callback.
RangingSession session = manager.createRangingSession(executor, callback);
// Create an OobInitiatorRangingConfig, which specifies the ranging parameters for
// the initiator role.
OobInitiatorRangingConfig config = new OobInitiatorRangingConfig.Builder()
.setFastestRangingInterval(Duration.ofMillis(100))
.setSlowestRangingInterval(Duration.ofMillis(5000))
.setRangingMode(RANGING_MODE_AUTO)
.setSecurityLevel(SECURITY_LEVEL_BASIC)
.addDeviceHandle(deviceHandle)
.build();
// Create a RangingPreference, which specifies the role (initiator) and
// configuration for the ranging session.
RangingPreference preference =
new RangingPreference.Builder(DEVICE_ROLE_INITIATOR, config).build();
// Start ranging session.
session.start(preference);
// If successful, the ranging data will be sent through callback#onResults
// Stop ranging session
session.stop();
}
// Starts a ranging session on the responder side.
void startRangingResponder(Context context, DeviceHandle deviceHandle, Executor executor, RangingSessionCallback callback) {
// Get the RangingManager which is the entry point for ranging module.
RangingManager manager = context.getSystemService(RangingManager.class);
// Create a new RangingSession using the provided executor and callback.
RangingSession session = manager.createRangingSession(executor, callback);
// Create an OobResponderRangingConfig, which specifies the ranging parameters for
// the responder role.
OobResponderRangingConfig config = new OobResponderRangingConfig.Builder( deviceHandle).build();
// Create a RangingPreference, which specifies the role (responder) and
// configuration for the ranging session.
RangingPreference preference =
new RangingPreference.Builder(DEVICE_ROLE_RESPONDER, config).build();
// Start the ranging session.
session.start(preference);
// Stop the ranging session
session.stop();
}
}
Совместимость UWB с устройствами iOS
Модуль определения расстояния поддерживает взаимодействие с устройствами iOS, использующими сверхширокополосную связь (UWB). Для определения расстояния с помощью устройства iOS необходимо использовать собственную реализацию OOB и настроить сеанс определения расстояния с определенными параметрами, соответствующими протоколу Apple Nearby Interaction Accessory Protocol . Для получения дополнительной информации обратитесь к примеру приложения .
При создании RangingPreference используйте RawRangingDevice и UwbRangingParams для указания конфигурации. Следующие параметры имеют решающее значение для совместимости с iOS:
- Идентификатор конфигурации: Используйте
UwbRangingParams.CONFIG_UNICAST_DS_TWR. - Информация о ключе сессии: Предоставьте массив байтов, содержащий идентификатор поставщика и статический вектор инициализации STS.
- Сложный канал: установите номер канала и индекс преамбулы в соответствии с конфигурацией устройства iOS.
Приведенный ниже фрагмент кода демонстрирует, как создать RangingPreference для определения расстояния до инициирующего устройства с помощью iOS-ответчика:
Котлин
// Create UwbRangingParams with iOS-specific configuration
val uwbRangingParams = UwbRangingParams.Builder(
sessionId,
UwbRangingParams.CONFIG_UNICAST_DS_TWR,
sourceAddress,
destinationAddress
)
.setComplexChannel(
UwbComplexChannel.Builder()
.setChannel(channelNumber)
.setPreambleIndex(preambleIndex)
.build()
)
.setRangingUpdateRate(updateRate)
.setSessionKeyInfo(sessionKeyInfo) // Vendor ID + STS IV
.setSlotDuration(slotDuration)
.build()
// Create RawRangingDevice
val rawRangingDevice = RawRangingDevice.Builder()
.setRangingDevice(RangingDevice.Builder().build())
.setUwbRangingParams(uwbRangingParams)
.build()
// Create SessionConfig
val sessionConfig = SessionConfig.Builder()
.setAngleOfArrivalNeeded(true)
.setDataNotificationConfig(DataNotificationConfig.Builder()
.setNotificationConfigType(DataNotificationConfig.NOTIFICATION_CONFIG_ENABLE)
.build())
.build()
// Create RangingPreference for the initiator
val preference = RangingPreference.Builder(
RangingPreference.DEVICE_ROLE_INITIATOR,
RawInitiatorRangingConfig.Builder()
.addRawRangingDevice(rawRangingDevice)
.build()
)
.setSessionConfig(sessionConfig)
.build()
Java
// Create UwbRangingParams with iOS-specific configuration
UwbRangingParams uwbRangingParams = new UwbRangingParams.Builder(
sessionId,
UwbRangingParams.CONFIG_UNICAST_DS_TWR,
sourceAddress,
destinationAddress)
.setComplexChannel(new UwbComplexChannel.Builder()
.setChannel(channelNumber)
.setPreambleIndex(preambleIndex)
.build())
.setRangingUpdateRate(updateRate)
.setSessionKeyInfo(sessionKeyInfo) // Vendor ID + STS IV
.setSlotDuration(slotDuration)
.build();
// Create RawRangingDevice
RawRangingDevice rawRangingDevice = new RawRangingDevice.Builder()
.setRangingDevice(new RangingDevice.Builder().build())
.setUwbRangingParams(uwbRangingParams)
.build();
// Create SessionConfig
SessionConfig sessionConfig = new SessionConfig.Builder()
.setAngleOfArrivalNeeded(true)
.setDataNotificationConfig(new DataNotificationConfig.Builder()
.setNotificationConfigType(DataNotificationConfig.NOTIFICATION_CONFIG_ENABLE)
.build())
.build();
// Create RangingPreference for the initiator
RangingPreference preference = new RangingPreference.Builder(
RangingPreference.DEVICE_ROLE_INITIATOR,
new RawInitiatorRangingConfig.Builder()
.addRawRangingDevice(rawRangingDevice)
.build())
.setSessionConfig(sessionConfig)
.build();
Пример приложения
Полный пример использования модуля «Измерение расстояния» можно найти в демонстрационном приложении в AOSP. Это демонстрационное приложение охватывает все технологии измерения расстояния, поддерживаемые модулем «Измерение расстояния», и включает в себя сценарии для обоих поддерживаемых типов сессий.
Совместимость UWB с устройствами iOS
Демонстрационное приложение для Android поддерживает запуск сеанса измерения расстояния по протоколу UWB с помощью демонстрационного приложения для iOS .
