Вы можете использовать функцию определения местоположения Wi-Fi, предоставляемую API Wi-Fi RTT (Round-Trip-Time), для измерения расстояния до ближайших точек доступа Wi-Fi с поддержкой RTT и одноранговых устройств Wi-Fi Aware .
Если вы измеряете расстояние до трех или более точек доступа, вы можете использовать алгоритм мультилатерации для оценки положения устройства, которое лучше всего соответствует этим измерениям. Результат обычно имеет точность в пределах 1-2 метров.
Благодаря такой точности вы можете разрабатывать детальные сервисы на основе определения местоположения, такие как внутренняя навигация, однозначное голосовое управление (например, «Включи этот свет») и предоставление информации на основе местоположения (например, «Есть ли специальные предложения на этот продукт?»).
Запрашивающему устройству не нужно подключаться к точкам доступа для измерения расстояния с помощью Wi-Fi RTT. Для сохранения конфиденциальности только запрашивающее устройство может определить расстояние до точки доступа; у точек доступа нет этой информации. Операции Wi-Fi RTT не ограничены для приложений переднего плана, но ограничены для фоновых приложений.
Wi-Fi RTT и связанные с ним возможности точного измерения времени (FTM) определены стандартом IEEE 802.11-2016. Wi-Fi RTT требует точного измерения времени, предоставляемого FTM, поскольку он вычисляет расстояние между двумя устройствами, измеряя время, необходимое пакету для прохождения кругового пути между устройствами, и умножая это время на скорость света.
В Android 15 (уровень API 35) появилась поддержка нетриггерного (NTB) ранжирования IEEE 802.11az.
Различия в реализации в зависимости от версии Android
Wi-Fi RTT был представлен в Android 9 (уровень API 28). При использовании этого протокола для определения местоположения устройства с помощью мультилатерации с устройствами под управлением Android 9 вам необходимо иметь доступ к данным о местоположении предопределенных точек доступа (AP) в вашем приложении. Вы сами решаете, как хранить и извлекать эти данные.
На устройствах под управлением Android 10 (уровень API 29) и выше данные о местоположении AP могут быть представлены в виде объектов ResponderLocation
, которые включают широту, долготу и высоту. Для точек доступа Wi-Fi RTT, которые поддерживают информацию о конфигурации местоположения/отчет Civic Location (данные LCI/LCR), протокол вернет объект ResponderLocation
во время процесса ранжирования .
Эта функция позволяет приложениям напрямую запрашивать у точек доступа их местоположение, а не сохранять эту информацию заранее. Таким образом, ваше приложение может находить точки доступа и определять их местоположение, даже если они не были известны ранее, например, когда пользователь входит в новое здание.
Поддержка диапазона IEEE 802.11az NTB доступна на устройствах под управлением Android 15 (уровень API 35) и выше. Это означает, что если устройство поддерживает режим инициатора IEEE 802.11az NTB (указывается WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR
), ваше приложение может найти точки доступа, поддерживающие как IEEE 802.11mc, так и IEEE 802.11az, с помощью одного запроса диапазона. API RangingResult
был расширен для предоставления информации о минимальном и максимальном значении, которое может использоваться для интервала между измерениями диапазона, оставляя точный интервал под контролем вашего приложения.
Требования
- Аппаратное обеспечение устройства, отправляющего запрос на определение диапазона, должно реализовывать стандарт 802.11-2016 FTM или стандарт 802.11az (определение диапазона без триггера).
- Устройство, отправляющее запрос на определение диапазона, должно работать под управлением Android 9 (уровень API 28) или более поздней версии. Определение диапазона без триггера IEEE 802.11az включено на устройствах под управлением Android 15 (уровень API 35) и выше.
- На устройстве, отправляющем запрос на определение местоположения, должны быть включены службы определения местоположения и включено сканирование Wi-Fi (в разделе «Настройки» > «Местоположение »).
- Если приложение, которое делает запрос на определение дальности, нацелено на Android 13 (уровень API 33) или выше, оно должно иметь разрешение
NEARBY_WIFI_DEVICES
. Если такое приложение нацелено на более раннюю версию Android, оно должно иметь разрешениеACCESS_FINE_LOCATION
. - Приложение должно запрашивать диапазон точек доступа, пока приложение видимо или находится в фоновом режиме. Приложение не может получить доступ к информации о местоположении из фонового режима .
- Точка доступа должна реализовывать стандарт IEEE 802.11-2016 FTM или стандарт IEEE 802.11az (диапазон без триггера).
Настраивать
Чтобы настроить приложение для использования Wi-Fi RTT, выполните следующие действия.
1. Запросить разрешения
Запросите следующие разрешения в манифесте вашего приложения:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- If your app targets Android 13 (API level 33)
or higher, you must declare the NEARBY_WIFI_DEVICES permission. -->
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
<!-- If your app derives location information from Wi-Fi APIs,
don't include the "usesPermissionFlags" attribute. -->
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
<!-- If any feature in your app relies on precise location
information, don't include the "maxSdkVersion"
attribute. -->
android:maxSdkVersion="32" />
Разрешения NEARBY_WIFI_DEVICES
и ACCESS_FINE_LOCATION
являются опасными разрешениями, поэтому вам необходимо запрашивать их во время выполнения каждый раз, когда пользователь хочет выполнить операцию сканирования RTT. Вашему приложению необходимо будет запросить разрешение пользователя, если оно еще не было предоставлено. Для получения дополнительной информации о разрешениях во время выполнения см. раздел Запрос разрешений приложения .
2. Проверьте, поддерживает ли устройство Wi-Fi RTT.
Чтобы проверить, поддерживает ли устройство Wi-Fi RTT, используйте API PackageManager
:
Котлин
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
Ява
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
3. Проверьте, доступен ли Wi-Fi RTT
Wi-Fi RTT может существовать на устройстве, но может быть недоступен, поскольку пользователь отключил Wi-Fi. В зависимости от возможностей оборудования и прошивки некоторые устройства могут не поддерживать Wi-Fi RTT, если используется SoftAP или модем. Чтобы проверить, доступен ли Wi-Fi RTT, вызовите isAvailable()
.
Доступность Wi-Fi RTT может измениться в любое время. Ваше приложение должно зарегистрировать BroadcastReceiver
для получения ACTION_WIFI_RTT_STATE_CHANGED
, который отправляется при изменении доступности. Когда ваше приложение получает намерение трансляции, оно должно проверить текущее состояние доступности и соответствующим образом скорректировать свое поведение.
Например:
Котлин
val filter = IntentFilter(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED) val myReceiver = object: BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (wifiRttManager.isAvailable) { … } else { … } } } context.registerReceiver(myReceiver, filter)
Ява
IntentFilter filter = new IntentFilter(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED); BroadcastReceiver myReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (wifiRttManager.isAvailable()) { … } else { … } } }; context.registerReceiver(myReceiver, filter);
Более подробную информацию см. в разделе Трансляции .
Создать запрос на ранжирование
Запрос на определение диапазона ( RangingRequest
) создается путем указания списка точек доступа или пиров Wi-Fi Aware, для которых запрашивается диапазон. Несколько точек доступа или пиров Wi-Fi Aware могут быть указаны в одном запросе на определение диапазона; расстояния до всех устройств измеряются и возвращаются.
Например, запрос может использовать метод addAccessPoint()
для указания точки доступа, до которой необходимо измерить расстояние:
Котлин
val req: RangingRequest = RangingRequest.Builder().run { addAccessPoint(ap1ScanResult) addAccessPoint(ap2ScanResult) build() }
Ява
RangingRequest.Builder builder = new RangingRequest.Builder(); builder.addAccessPoint(ap1ScanResult); builder.addAccessPoint(ap2ScanResult); RangingRequest req = builder.build();
Точка доступа идентифицируется ее объектом ScanResult
, который можно получить, вызвав WifiManager.getScanResults()
. Вы можете использовать addAccessPoints(List<ScanResult>)
для добавления нескольких точек доступа в пакетном режиме.
Объекты ScanResult
могут содержать как поддерживаемые AP IEEE 802.11mc ( is80211mcResponder()
), так и IEEE 802.11az нетриггерного ранжирования ( is80211azNtbResponder()
). Устройства, поддерживающие ранжирование IEEE 802.11az NTB, выполняют либо ранжирование 802.11mc, либо 802.11az в зависимости от возможностей AP, по умолчанию используется 802.11az, если AP поддерживает оба. Устройства, не поддерживающие IEEE 802.11az, выполняют все ранжирования с использованием протокола IEEE 802.11mc.
Аналогично, запрос на определение диапазона может добавить пир Wi-Fi Aware, используя либо его MAC-адрес, либо его PeerHandle
, используя методы addWifiAwarePeer(MacAddress peer)
и addWifiAwarePeer(PeerHandle peer)
соответственно. Для получения дополнительной информации об обнаружении пиров Wi-Fi Aware см. документацию Wi-Fi Aware .
Запрос ранжирования
Приложение отправляет запрос на ранжирование с помощью метода WifiRttManager.startRanging()
и предоставляет следующее: RangingRequest
для указания операции, Executor
для указания контекста обратного вызова и RangingResultCallback
для получения результатов.
Например:
Котлин
val mgr = context.getSystemService(Context.WIFI_RTT_RANGING_SERVICE) as WifiRttManager val request: RangingRequest = myRequest mgr.startRanging(request, executor, object : RangingResultCallback() { override fun onRangingResults(results: List<RangingResult>) { … } override fun onRangingFailure(code: Int) { … } })
Ява
WifiRttManager mgr = (WifiRttManager) Context.getSystemService(Context.WIFI_RTT_RANGING_SERVICE); RangingRequest request ...; mgr.startRanging(request, executor, new RangingResultCallback() { @Override public void onRangingFailure(int code) { … } @Override public void onRangingResults(List<RangingResult> results) { … } });
Операция ранжирования выполняется асинхронно, а результаты ранжирования возвращаются в одном из обратных вызовов RangingResultCallback
:
- Если вся операция ранжирования завершается неудачей, обратный вызов
onRangingFailure
запускается с кодом состояния, описанным вRangingResultCallback
. Такой сбой может произойти, если служба не может выполнить операцию ранжирования в данный момент, например, из-за того, что Wi-Fi отключен, из-за того, что приложение запросило слишком много операций ранжирования и было ограничено, или из-за проблемы с разрешениями. - Когда операция ранжирования завершается, запускается обратный вызов
onRangingResults
со списком результатов, соответствующих списку запросов — один результат для каждого запроса. Порядок результатов не обязательно соответствует порядку запросов. Обратите внимание, что операция ранжирования может завершиться, но каждый результат может по-прежнему указывать на сбой этого конкретного измерения.
Интерпретировать результаты ранжирования
Каждый из результатов, возвращаемых функцией обратного вызова onRangingResults
, указывается объектом RangingResult
. При каждом запросе выполните следующие действия.
1. Определите запрос
Определите запрос на основе информации, предоставленной при создании RangingRequest
: чаще всего это MAC-адрес, предоставленный в ScanResult
, идентифицирующий точку доступа. MAC-адрес можно получить из результата ранжирования с помощью метода getMacAddress()
.
Список результатов ранжирования может располагаться в ином порядке, чем одноранговые узлы (точки доступа), указанные в запросе ранжирования, поэтому для идентификации однорангового узла следует использовать MAC-адрес, а не порядок результатов.
2. Определите, было ли каждое измерение успешным.
Чтобы определить, было ли измерение успешным, используйте метод getStatus()
. Любое значение, отличное от STATUS_SUCCESS
указывает на сбой. Сбой означает, что все остальные поля этого результата (кроме идентификации запроса выше) недействительны, и соответствующий метод get*
завершится ошибкой с исключением IllegalStateException
.
3. Получите результаты для каждого успешного измерения.
Для каждого успешного измерения ( RangingResult
) вы можете получить значения результатов с помощью соответствующих методов get
:
Расстояние в мм и стандартное отклонение измерения:
RSSI пакетов, используемых для измерений:
Время в миллисекундах, в течение которого было выполнено измерение (указывает время с момента загрузки):
Количество предпринятых попыток измерений и количество успешных измерений (на которых основаны измерения расстояния):
Минимальное и максимальное время ожидания клиентским устройством между измерениями 11az NTB:
getMinTimeBetweenNtbMeasurementsMicros()
иgetMaxTimeBetweenNtbMeasurementsMicros()
возвращают минимальное и максимальное время. Если следующее измерение ранжирования запрашивается до истечения минимального времени, то API возвращает кэшированный результат ранжирования. Если следующее измерение ранжирования запрашивается после истечения максимального времени, то API завершает сеанс ранжирования без триггера и согласовывает новый сеанс ранжирования с отвечающей станцией. Вам следует избегать запроса нового сеанса ранжирования, поскольку это добавляет накладные расходы к времени измерения ранжирования. Чтобы в полной мере воспользоваться эффективностью ранжирования без триггера 802.11az, запустите следующий запрос ранжирования между минимальным и максимальным временем измерения, указанным в предыдущем измеренииRangingResult
.Повторения длинного учебного поля (LTF), которые станции-ответчики и инициаторы использовали в преамбуле для IEEE 802.11az NTB, приводят к следующему:
Количество переданных и принятых пространственно-временных потоков (STS), которые станция-инициатор использовала для результата IEEE 802.11az NTB:
Устройства Android, поддерживающие WiFi-RTT
В следующих таблицах перечислены некоторые телефоны , точки доступа , а также устройства для розничной торговли, складирования и распределительных центров , которые поддерживают WiFi-RTT. Они далеко не полные. Мы призываем вас обратиться к нам , чтобы мы перечислили здесь ваши продукты с поддержкой RTT.
Точки доступа
Производитель и модель | Дата поддержки | Протокол |
---|---|---|
Nest Wifi Pro (Wi-Fi 6E) | Поддерживается | мс |
Compulab WILD AP | Поддерживается | мс |
Google Wi-Fi | Поддерживается | мс |
Маршрутизатор Google Nest Wi-Fi | Поддерживается | мс |
Точка Wi-Fi Google Nest | Поддерживается | мс |
Аруба AP-635 | Поддерживается | мс |
Cisco 9130 | Поддерживается | мс |
Сиско 9136 | Поддерживается | мс |
Cisco 9166 | Поддерживается | мс |
Cisco 9164 | Поддерживается | мс |
Cisco CW9172I | Поддерживается | мк/аз |
Cisco CW9172H | Поддерживается | мк/аз |
Cisco CW9176I | Поддерживается | мк/аз |
Cisco CW9178I | Поддерживается | мк/аз |
Аруба AP-505 | Поддерживается | мс |
Аруба AP-515 | Поддерживается | мс |
Аруба AP-575 | Поддерживается | мс |
Аруба AP-518 | Поддерживается | мс |
Аруба AP-505H | Поддерживается | мс |
Аруба AP-565 | Поддерживается | мс |
Аруба AP-535 | Поддерживается | мс |
Аруба AP567 | Поддерживается | мс |
Аруба AP577 | Поддерживается | мс |
Аруба AP555 | Поддерживается | мс |
Аруба AP635 | Поддерживается | мс |
Аруба AP655 | Поддерживается | мс |
Аруба AP615 | Поддерживается | мс |
Аруба AP734 | Поддерживается | мк/аз |
Аруба AP735 | Поддерживается | мк/аз |
Аруба AP754 | Поддерживается | мк/аз |
Аруба AP755 | Поддерживается | мк/аз |
Телефоны
Производитель и модель | Android-версия |
---|---|
Google Pixel 9 Pro XL | 14+ |
Google Пиксель 9 | 14+ |
Google Пиксель 9 Про | 14+ |
Google Pixel 9 Pro XL | 14+ |
Google Пиксель 7а | 14+ |
Google Пиксель 7 | 14+ |
Google Пиксель 8 | 14+ |
Google Пиксель 8 Про | 14+ |
Google Пиксель 8а | 14+ |
Samsung SM-S918B | 14+ |
Samsung SM-A515F | 14+ |
Google Пиксель 9 Про | 14+ |
Samsung SM-A546E | 14+ |
Samsung SM-S928B | 14+ |
Samsung SM-A217F | 14+ |
Samsung SM-A715F | 14+ |
Samsung SM-A528B | 14+ |
Samsung SM-A135F | 14+ |
Samsung SM-S911B | 14+ |
Xiaomi 21091116AI | 14+ |
Google Пиксель 9 | 14+ |
Samsung SM-A127F | 14+ |
Google Пиксель 7 Про | 14+ |
Samsung SM-A556E | 14+ |
Пиксель 6 | 9.0+ |
Пиксель 6 Про | 9.0+ |
Пиксель 5 | 9.0+ |
Пиксель 5а | 9.0+ |
Пиксель 5а 5G | 9.0+ |
Xiaomi Mi 10 Pro | 9.0+ |
Xiaomi Mi10 | 9.0+ |
Xiaomi Redmi Mi 9T Pro | 9.0+ |
Xiaomi Mi9T | 9.0+ |
Xiaomi Mi9 | 9.0+ |
Xiaomi Mi Note 10 | 9.0+ |
Xiaomi Mi Note 10 Lite | 9.0+ |
Xiaomi Redmi Note 9S | 9.0+ |
Xiaomi Redmi Note 9 Pro | 9.0+ |
Xiaomi Redmi Note 8T | 9.0+ |
Xiaomi Redmi Note 8 | 9.0+ |
Xiaomi Redmi K30 Pro | 9.0+ |
Xiaomi Redmi K20 Pro | 9.0+ |
Xiaomi Redmi K20 | 9.0+ |
Xiaomi Redmi Note 5 Pro | 9.0+ |
Xiaomi Mi CC9 Pro | 9.0+ |
LG G8X ThinQ | 9.0+ |
LG V50S ThinQ | 9.0+ |
LG V60 ThinQ | 9.0+ |
LG V30 | 9.0+ |
Samsung Galaxy Note 10+ 5G | 9.0+ |
Samsung Galaxy S20+ 5G | 9.0+ |
Samsung Galaxy S20+ | 9.0+ |
Samsung Galaxy S20 5G | 9.0+ |
Samsung Galaxy S20 Ультра 5G | 9.0+ |
Samsung Galaxy S20 | 9.0+ |
Samsung Galaxy Note 10+ | 9.0+ |
Samsung Galaxy Note 10 5G | 9.0+ |
Samsung Galaxy Note 10 | 9.0+ |
Самсунг А9 Про | 9.0+ |
Google Пиксель 4 XL | 9.0+ |
Google Пиксель 4 | 9.0+ |
Google Пиксель 4а | 9.0+ |
Google Пиксель 3 XL | 9.0+ |
Google Пиксель 3 | 9.0+ |
Google Pixel 3a XL | 9.0+ |
Google Пиксель 3а | 9.0+ |
Google Пиксель 2 XL | 9.0+ |
Google Пиксель 2 | 9.0+ |
Google Пиксель 1 XL | 9.0+ |
Google Пиксель 1 | 9.0+ |
Поко X2 | 9.0+ |
Sharp Aquos R3 SH-04L | 9.0+ |
Устройства для розничной торговли, складирования и распределительных центров
Производитель и модель | Android-версия |
---|---|
Зебра PS20 | 10.0+ |
Зебра TC52/TC52HC | 10.0+ |
Зебра TC57 | 10.0+ |
Зебра TC72 | 10.0+ |
Зебра TC77 | 10.0+ |
Зебра MC93 | 10.0+ |
Зебра TC8300 | 10.0+ |
Зебра VC8300 | 10.0+ |
Зебра EC30 | 10.0+ |
Зебра ET51 | 10.0+ |
Зебра ET56 | 10.0+ |
Зебра Л10 | 10.0+ |
Зебра CC600/CC6000 | 10.0+ |
Зебра MC3300x | 10.0+ |
Зебра MC330x | 10.0+ |
Зебра TC52x | 10.0+ |
Зебра TC57x | 10.0+ |
Zebra EC50 (LAN и HC) | 10.0+ |
Зебра EC55 (WAN) | 10.0+ |
Зебра WT6300 | 10.0+ |
Скорпион X5 | 10.0+ |
Вы можете использовать функцию определения местоположения Wi-Fi, предоставляемую API Wi-Fi RTT (Round-Trip-Time), для измерения расстояния до ближайших точек доступа Wi-Fi с поддержкой RTT и одноранговых устройств Wi-Fi Aware .
Если вы измеряете расстояние до трех или более точек доступа, вы можете использовать алгоритм мультилатерации для оценки положения устройства, которое лучше всего соответствует этим измерениям. Результат обычно имеет точность в пределах 1-2 метров.
Благодаря такой точности вы можете разрабатывать детальные сервисы на основе определения местоположения, такие как внутренняя навигация, однозначное голосовое управление (например, «Включи этот свет») и предоставление информации на основе местоположения (например, «Есть ли специальные предложения на этот продукт?»).
Запрашивающему устройству не нужно подключаться к точкам доступа для измерения расстояния с помощью Wi-Fi RTT. Для сохранения конфиденциальности только запрашивающее устройство может определить расстояние до точки доступа; у точек доступа нет этой информации. Операции Wi-Fi RTT не ограничены для приложений переднего плана, но ограничены для фоновых приложений.
Wi-Fi RTT и связанные с ним возможности точного измерения времени (FTM) определены стандартом IEEE 802.11-2016. Wi-Fi RTT требует точного измерения времени, предоставляемого FTM, поскольку он вычисляет расстояние между двумя устройствами, измеряя время, необходимое пакету для прохождения кругового пути между устройствами, и умножая это время на скорость света.
В Android 15 (уровень API 35) появилась поддержка нетриггерного (NTB) ранжирования IEEE 802.11az.
Различия в реализации в зависимости от версии Android
Wi-Fi RTT был представлен в Android 9 (уровень API 28). При использовании этого протокола для определения местоположения устройства с помощью мультилатерации с устройствами под управлением Android 9 вам необходимо иметь доступ к данным о местоположении предопределенных точек доступа (AP) в вашем приложении. Вы сами решаете, как хранить и извлекать эти данные.
На устройствах под управлением Android 10 (уровень API 29) и выше данные о местоположении AP могут быть представлены в виде объектов ResponderLocation
, которые включают широту, долготу и высоту. Для точек доступа Wi-Fi RTT, которые поддерживают информацию о конфигурации местоположения/отчет Civic Location (данные LCI/LCR), протокол вернет объект ResponderLocation
во время процесса ранжирования .
Эта функция позволяет приложениям напрямую запрашивать у точек доступа их местоположение, а не сохранять эту информацию заранее. Таким образом, ваше приложение может находить точки доступа и определять их местоположение, даже если они не были известны ранее, например, когда пользователь входит в новое здание.
Поддержка диапазона IEEE 802.11az NTB доступна на устройствах под управлением Android 15 (уровень API 35) и выше. Это означает, что если устройство поддерживает режим инициатора IEEE 802.11az NTB (указывается WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR
), ваше приложение может найти точки доступа, поддерживающие как IEEE 802.11mc, так и IEEE 802.11az, с помощью одного запроса диапазона. API RangingResult
был расширен для предоставления информации о минимальном и максимальном значении, которое может использоваться для интервала между измерениями диапазона, оставляя точный интервал под контролем вашего приложения.
Требования
- Аппаратное обеспечение устройства, отправляющего запрос на определение диапазона, должно реализовывать стандарт 802.11-2016 FTM или стандарт 802.11az (определение диапазона без триггера).
- Устройство, отправляющее запрос на определение диапазона, должно работать под управлением Android 9 (уровень API 28) или более поздней версии. Определение диапазона без триггера IEEE 802.11az включено на устройствах под управлением Android 15 (уровень API 35) и выше.
- На устройстве, отправляющем запрос на определение местоположения, должны быть включены службы определения местоположения и включено сканирование Wi-Fi (в разделе «Настройки» > «Местоположение »).
- Если приложение, которое делает запрос на определение дальности, нацелено на Android 13 (уровень API 33) или выше, оно должно иметь разрешение
NEARBY_WIFI_DEVICES
. Если такое приложение нацелено на более раннюю версию Android, оно должно иметь разрешениеACCESS_FINE_LOCATION
. - Приложение должно запрашивать диапазон точек доступа, пока приложение видимо или находится в фоновом режиме. Приложение не может получить доступ к информации о местоположении из фонового режима .
- Точка доступа должна реализовывать стандарт IEEE 802.11-2016 FTM или стандарт IEEE 802.11az (диапазон без триггера).
Настраивать
Чтобы настроить приложение для использования Wi-Fi RTT, выполните следующие действия.
1. Запросить разрешения
Запросите следующие разрешения в манифесте вашего приложения:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- If your app targets Android 13 (API level 33)
or higher, you must declare the NEARBY_WIFI_DEVICES permission. -->
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
<!-- If your app derives location information from Wi-Fi APIs,
don't include the "usesPermissionFlags" attribute. -->
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
<!-- If any feature in your app relies on precise location
information, don't include the "maxSdkVersion"
attribute. -->
android:maxSdkVersion="32" />
Разрешения NEARBY_WIFI_DEVICES
и ACCESS_FINE_LOCATION
являются опасными разрешениями, поэтому вам необходимо запрашивать их во время выполнения каждый раз, когда пользователь хочет выполнить операцию сканирования RTT. Вашему приложению необходимо будет запросить разрешение пользователя, если оно еще не было предоставлено. Для получения дополнительной информации о разрешениях во время выполнения см. раздел Запрос разрешений приложения .
2. Проверьте, поддерживает ли устройство Wi-Fi RTT.
Чтобы проверить, поддерживает ли устройство Wi-Fi RTT, используйте API PackageManager
:
Котлин
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
Ява
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
3. Проверьте, доступен ли Wi-Fi RTT
Wi-Fi RTT может существовать на устройстве, но может быть недоступен, поскольку пользователь отключил Wi-Fi. В зависимости от возможностей оборудования и прошивки некоторые устройства могут не поддерживать Wi-Fi RTT, если используется SoftAP или модем. Чтобы проверить, доступен ли Wi-Fi RTT, вызовите isAvailable()
.
Доступность Wi-Fi RTT может измениться в любое время. Ваше приложение должно зарегистрировать BroadcastReceiver
для получения ACTION_WIFI_RTT_STATE_CHANGED
, который отправляется при изменении доступности. Когда ваше приложение получает намерение трансляции, оно должно проверить текущее состояние доступности и соответствующим образом скорректировать свое поведение.
Например:
Котлин
val filter = IntentFilter(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED) val myReceiver = object: BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (wifiRttManager.isAvailable) { … } else { … } } } context.registerReceiver(myReceiver, filter)
Ява
IntentFilter filter = new IntentFilter(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED); BroadcastReceiver myReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (wifiRttManager.isAvailable()) { … } else { … } } }; context.registerReceiver(myReceiver, filter);
Более подробную информацию см. в разделе Трансляции .
Создать запрос на ранжирование
Запрос на определение диапазона ( RangingRequest
) создается путем указания списка точек доступа или пиров Wi-Fi Aware, для которых запрашивается диапазон. Несколько точек доступа или пиров Wi-Fi Aware могут быть указаны в одном запросе на определение диапазона; расстояния до всех устройств измеряются и возвращаются.
Например, запрос может использовать метод addAccessPoint()
для указания точки доступа, до которой необходимо измерить расстояние:
Котлин
val req: RangingRequest = RangingRequest.Builder().run { addAccessPoint(ap1ScanResult) addAccessPoint(ap2ScanResult) build() }
Ява
RangingRequest.Builder builder = new RangingRequest.Builder(); builder.addAccessPoint(ap1ScanResult); builder.addAccessPoint(ap2ScanResult); RangingRequest req = builder.build();
Точка доступа идентифицируется ее объектом ScanResult
, который можно получить, вызвав WifiManager.getScanResults()
. Вы можете использовать addAccessPoints(List<ScanResult>)
для добавления нескольких точек доступа в пакетном режиме.
Объекты ScanResult
могут содержать как поддерживаемые AP IEEE 802.11mc ( is80211mcResponder()
), так и IEEE 802.11az нетриггерного ранжирования ( is80211azNtbResponder()
). Устройства, поддерживающие ранжирование IEEE 802.11az NTB, выполняют либо ранжирование 802.11mc, либо 802.11az в зависимости от возможностей AP, по умолчанию используется 802.11az, если AP поддерживает оба. Устройства, не поддерживающие IEEE 802.11az, выполняют все ранжирования с использованием протокола IEEE 802.11mc.
Аналогично, запрос на определение диапазона может добавить пир Wi-Fi Aware, используя либо его MAC-адрес, либо его PeerHandle
, используя методы addWifiAwarePeer(MacAddress peer)
и addWifiAwarePeer(PeerHandle peer)
соответственно. Для получения дополнительной информации об обнаружении пиров Wi-Fi Aware см. документацию Wi-Fi Aware .
Запрос ранжирования
Приложение отправляет запрос на ранжирование с помощью метода WifiRttManager.startRanging()
и предоставляет следующее: RangingRequest
для указания операции, Executor
для указания контекста обратного вызова и RangingResultCallback
для получения результатов.
Например:
Котлин
val mgr = context.getSystemService(Context.WIFI_RTT_RANGING_SERVICE) as WifiRttManager val request: RangingRequest = myRequest mgr.startRanging(request, executor, object : RangingResultCallback() { override fun onRangingResults(results: List<RangingResult>) { … } override fun onRangingFailure(code: Int) { … } })
Ява
WifiRttManager mgr = (WifiRttManager) Context.getSystemService(Context.WIFI_RTT_RANGING_SERVICE); RangingRequest request ...; mgr.startRanging(request, executor, new RangingResultCallback() { @Override public void onRangingFailure(int code) { … } @Override public void onRangingResults(List<RangingResult> results) { … } });
Операция ранжирования выполняется асинхронно, а результаты ранжирования возвращаются в одном из обратных вызовов RangingResultCallback
:
- Если вся операция ранжирования завершается неудачей, обратный вызов
onRangingFailure
запускается с кодом состояния, описанным вRangingResultCallback
. Такой сбой может произойти, если служба не может выполнить операцию ранжирования в данный момент, например, из-за того, что Wi-Fi отключен, из-за того, что приложение запросило слишком много операций ранжирования и было ограничено, или из-за проблемы с разрешениями. - Когда операция ранжирования завершается, запускается обратный вызов
onRangingResults
со списком результатов, соответствующих списку запросов — один результат для каждого запроса. Порядок результатов не обязательно соответствует порядку запросов. Обратите внимание, что операция ранжирования может завершиться, но каждый результат может по-прежнему указывать на сбой этого конкретного измерения.
Интерпретировать результаты ранжирования
Каждый из результатов, возвращаемых функцией обратного вызова onRangingResults
, указывается объектом RangingResult
. При каждом запросе выполните следующие действия.
1. Определите запрос
Определите запрос на основе информации, предоставленной при создании RangingRequest
: чаще всего это MAC-адрес, предоставленный в ScanResult
, идентифицирующий точку доступа. MAC-адрес можно получить из результата ранжирования с помощью метода getMacAddress()
.
Список результатов ранжирования может располагаться в ином порядке, чем одноранговые узлы (точки доступа), указанные в запросе ранжирования, поэтому для идентификации однорангового узла следует использовать MAC-адрес, а не порядок результатов.
2. Определите, было ли каждое измерение успешным.
Чтобы определить, было ли измерение успешным, используйте метод getStatus()
. Любое значение, отличное от STATUS_SUCCESS
указывает на сбой. Сбой означает, что все остальные поля этого результата (кроме идентификации запроса выше) недействительны, и соответствующий метод get*
завершится ошибкой с исключением IllegalStateException
.
3. Получите результаты для каждого успешного измерения.
Для каждого успешного измерения ( RangingResult
) вы можете получить значения результатов с помощью соответствующих методов get
:
Расстояние в мм и стандартное отклонение измерения:
RSSI пакетов, используемых для измерений:
Время в миллисекундах, в течение которого было выполнено измерение (указывает время с момента загрузки):
Количество предпринятых попыток измерений и количество успешных измерений (на которых основаны измерения расстояния):
Минимальное и максимальное время ожидания клиентским устройством между измерениями 11az NTB:
getMinTimeBetweenNtbMeasurementsMicros()
иgetMaxTimeBetweenNtbMeasurementsMicros()
возвращают минимальное и максимальное время. Если следующее измерение ранжирования запрашивается до истечения минимального времени, то API возвращает кэшированный результат ранжирования. Если следующее измерение ранжирования запрашивается после истечения максимального времени, то API завершает сеанс ранжирования без триггера и согласовывает новый сеанс ранжирования с отвечающей станцией. Вам следует избегать запроса нового сеанса ранжирования, поскольку это добавляет накладные расходы к времени измерения ранжирования. Чтобы в полной мере воспользоваться эффективностью ранжирования без триггера 802.11az, запустите следующий запрос ранжирования между минимальным и максимальным временем измерения, указанным в предыдущем измеренииRangingResult
.Повторения длинного учебного поля (LTF), которые станции-ответчики и инициаторы использовали в преамбуле для IEEE 802.11az NTB, приводят к следующему:
Количество переданных и принятых пространственно-временных потоков (STS), которые станция-инициатор использовала для результата IEEE 802.11az NTB:
Устройства Android, поддерживающие WiFi-RTT
В следующих таблицах перечислены некоторые телефоны , точки доступа , а также устройства для розничной торговли, складирования и распределительных центров , которые поддерживают WiFi-RTT. Они далеко не полные. Мы призываем вас обратиться к нам , чтобы мы перечислили здесь ваши продукты с поддержкой RTT.
Точки доступа
Производитель и модель | Дата поддержки | Протокол |
---|---|---|
Nest Wifi Pro (Wi-Fi 6E) | Поддерживается | мс |
Compulab WILD AP | Поддерживается | мс |
Google Wi-Fi | Поддерживается | мс |
Маршрутизатор Google Nest Wi-Fi | Поддерживается | мс |
Точка Wi-Fi Google Nest | Поддерживается | мс |
Аруба AP-635 | Поддерживается | мс |
Cisco 9130 | Поддерживается | мс |
Сиско 9136 | Поддерживается | мс |
Cisco 9166 | Поддерживается | мс |
Cisco 9164 | Поддерживается | мс |
Cisco CW9172I | Поддерживается | мк/аз |
Cisco CW9172H | Поддерживается | мк/аз |
Cisco CW9176I | Поддерживается | мк/аз |
Cisco CW9178I | Поддерживается | мк/аз |
Аруба AP-505 | Поддерживается | мс |
Аруба AP-515 | Поддерживается | мс |
Аруба AP-575 | Поддерживается | мс |
Аруба AP-518 | Поддерживается | мс |
Аруба AP-505H | Поддерживается | мс |
Аруба AP-565 | Поддерживается | мс |
Аруба AP-535 | Поддерживается | мс |
Аруба AP567 | Поддерживается | мс |
Аруба AP577 | Поддерживается | мс |
Аруба AP555 | Поддерживается | мс |
Аруба AP635 | Поддерживается | мс |
Аруба AP655 | Поддерживается | мс |
Аруба AP615 | Поддерживается | мс |
Аруба AP734 | Поддерживается | мк/аз |
Аруба AP735 | Поддерживается | мк/аз |
Аруба AP754 | Поддерживается | мк/аз |
Аруба AP755 | Поддерживается | мк/аз |
Телефоны
Производитель и модель | Android-версия |
---|---|
Google Pixel 9 Pro XL | 14+ |
Google Пиксель 9 | 14+ |
Google Пиксель 9 Про | 14+ |
Google Pixel 9 Pro XL | 14+ |
Google Пиксель 7а | 14+ |
Google Пиксель 7 | 14+ |
Google Пиксель 8 | 14+ |
Google Пиксель 8 Про | 14+ |
Google Пиксель 8а | 14+ |
Samsung SM-S918B | 14+ |
Samsung SM-A515F | 14+ |
Google Пиксель 9 Про | 14+ |
Samsung SM-A546E | 14+ |
Samsung SM-S928B | 14+ |
Samsung SM-A217F | 14+ |
Samsung SM-A715F | 14+ |
Samsung SM-A528B | 14+ |
Samsung SM-A135F | 14+ |
Samsung SM-S911B | 14+ |
Xiaomi 21091116AI | 14+ |
Google Пиксель 9 | 14+ |
Samsung SM-A127F | 14+ |
Google Пиксель 7 Про | 14+ |
Samsung SM-A556E | 14+ |
Пиксель 6 | 9.0+ |
Пиксель 6 Про | 9.0+ |
Пиксель 5 | 9.0+ |
Пиксель 5а | 9.0+ |
Пиксель 5а 5G | 9.0+ |
Xiaomi Mi 10 Pro | 9.0+ |
Xiaomi Mi10 | 9.0+ |
Xiaomi Redmi Mi 9T Pro | 9.0+ |
Xiaomi Mi9T | 9.0+ |
Xiaomi Mi9 | 9.0+ |
Xiaomi Mi Note 10 | 9.0+ |
Xiaomi Mi Note 10 Lite | 9.0+ |
Xiaomi Redmi Note 9S | 9.0+ |
Xiaomi Redmi Note 9 Pro | 9.0+ |
Xiaomi Redmi Note 8T | 9.0+ |
Xiaomi Redmi Note 8 | 9.0+ |
Xiaomi Redmi K30 Pro | 9.0+ |
Xiaomi Redmi K20 Pro | 9.0+ |
Xiaomi Redmi K20 | 9.0+ |
Xiaomi Redmi Note 5 Pro | 9.0+ |
Xiaomi Mi CC9 Pro | 9.0+ |
LG G8X ThinQ | 9.0+ |
LG V50S ThinQ | 9.0+ |
LG V60 ThinQ | 9.0+ |
LG V30 | 9.0+ |
Samsung Galaxy Note 10+ 5G | 9.0+ |
Samsung Galaxy S20+ 5G | 9.0+ |
Samsung Galaxy S20+ | 9.0+ |
Samsung Galaxy S20 5G | 9.0+ |
Samsung Galaxy S20 Ультра 5G | 9.0+ |
Samsung Galaxy S20 | 9.0+ |
Samsung Galaxy Note 10+ | 9.0+ |
Samsung Galaxy Note 10 5G | 9.0+ |
Samsung Galaxy Note 10 | 9.0+ |
Самсунг А9 Про | 9.0+ |
Google Пиксель 4 XL | 9.0+ |
Google Пиксель 4 | 9.0+ |
Google Пиксель 4а | 9.0+ |
Google Пиксель 3 XL | 9.0+ |
Google Пиксель 3 | 9.0+ |
Google Pixel 3a XL | 9.0+ |
Google Пиксель 3а | 9.0+ |
Google Пиксель 2 XL | 9.0+ |
Google Пиксель 2 | 9.0+ |
Google Пиксель 1 XL | 9.0+ |
Google Пиксель 1 | 9.0+ |
Поко X2 | 9.0+ |
Sharp Aquos R3 SH-04L | 9.0+ |
Устройства для розничной торговли, складирования и распределительных центров
Производитель и модель | Android-версия |
---|---|
Зебра PS20 | 10.0+ |
Зебра TC52/TC52HC | 10.0+ |
Зебра TC57 | 10.0+ |
Зебра TC72 | 10.0+ |
Зебра TC77 | 10.0+ |
Зебра MC93 | 10.0+ |
Зебра TC8300 | 10.0+ |
Зебра VC8300 | 10.0+ |
Зебра EC30 | 10.0+ |
Зебра ET51 | 10.0+ |
Зебра ET56 | 10.0+ |
Зебра Л10 | 10.0+ |
Зебра CC600/CC6000 | 10.0+ |
Зебра MC3300x | 10.0+ |
Зебра MC330x | 10.0+ |
Зебра TC52x | 10.0+ |
Зебра TC57x | 10.0+ |
Zebra EC50 (LAN и HC) | 10.0+ |
Зебра EC55 (WAN) | 10.0+ |
Зебра WT6300 | 10.0+ |
Скорпион X5 | 10.0+ |