Расположение Wi-Fi: начиная с RTT

Вы можете использовать функцию определения местоположения 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 :

  • Расстояние в мм и стандартное отклонение измерения:

    getDistanceMm()

    getDistanceStdDevMm()

  • RSSI пакетов, используемых для измерений:

    getRssi()

  • Время в миллисекундах, в течение которого было выполнено измерение (указывает время с момента загрузки):

    getRangingTimestampMillis()

  • Количество предпринятых попыток измерений и количество успешных измерений (на которых основаны измерения расстояния):

    getNumAttemptedMeasurements()

    getNumSuccessfulMeasurements()

  • Минимальное и максимальное время ожидания клиентским устройством между измерениями 11az NTB:

    getMinTimeBetweenNtbMeasurementsMicros() и getMaxTimeBetweenNtbMeasurementsMicros() возвращают минимальное и максимальное время. Если следующее измерение ранжирования запрашивается до истечения минимального времени, то API возвращает кэшированный результат ранжирования. Если следующее измерение ранжирования запрашивается после истечения максимального времени, то API завершает сеанс ранжирования без триггера и согласовывает новый сеанс ранжирования с отвечающей станцией. Вам следует избегать запроса нового сеанса ранжирования, поскольку это добавляет накладные расходы к времени измерения ранжирования. Чтобы в полной мере воспользоваться эффективностью ранжирования без триггера 802.11az, запустите следующий запрос ранжирования между минимальным и максимальным временем измерения, указанным в предыдущем измерении RangingResult .

  • Повторения длинного учебного поля (LTF), которые станции-ответчики и инициаторы использовали в преамбуле для IEEE 802.11az NTB, приводят к следующему:

    get80211azResponderTxLtfRepetitionsCount()

    get80211azInitiatorTxLtfRepetitionsCount()

  • Количество переданных и принятых пространственно-временных потоков (STS), которые станция-инициатор использовала для результата IEEE 802.11az NTB:

    get80211azNumberOfTxSpatialStreams()

    get80211azNumberOfRxSpatialStreams()

Устройства 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 :

  • Расстояние в мм и стандартное отклонение измерения:

    getDistanceMm()

    getDistanceStdDevMm()

  • RSSI пакетов, используемых для измерений:

    getRssi()

  • Время в миллисекундах, в течение которого было выполнено измерение (указывает время с момента загрузки):

    getRangingTimestampMillis()

  • Количество предпринятых попыток измерений и количество успешных измерений (на которых основаны измерения расстояния):

    getNumAttemptedMeasurements()

    getNumSuccessfulMeasurements()

  • Минимальное и максимальное время ожидания клиентским устройством между измерениями 11az NTB:

    getMinTimeBetweenNtbMeasurementsMicros() и getMaxTimeBetweenNtbMeasurementsMicros() возвращают минимальное и максимальное время. Если следующее измерение ранжирования запрашивается до истечения минимального времени, то API возвращает кэшированный результат ранжирования. Если следующее измерение ранжирования запрашивается после истечения максимального времени, то API завершает сеанс ранжирования без триггера и согласовывает новый сеанс ранжирования с отвечающей станцией. Вам следует избегать запроса нового сеанса ранжирования, поскольку это добавляет накладные расходы к времени измерения ранжирования. Чтобы в полной мере воспользоваться эффективностью ранжирования без триггера 802.11az, запустите следующий запрос ранжирования между минимальным и максимальным временем измерения, указанным в предыдущем измерении RangingResult .

  • Повторения длинного учебного поля (LTF), которые станции-ответчики и инициаторы использовали в преамбуле для IEEE 802.11az NTB, приводят к следующему:

    get80211azResponderTxLtfRepetitionsCount()

    get80211azInitiatorTxLtfRepetitionsCount()

  • Количество переданных и принятых пространственно-временных потоков (STS), которые станция-инициатор использовала для результата IEEE 802.11az NTB:

    get80211azNumberOfTxSpatialStreams()

    get80211azNumberOfRxSpatialStreams()

Устройства 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+