Wi-Fi 位置情報: RTT を使用したレンジング(距離測定)

Wi-Fi RTT(ラウンドトリップ時間)API が提供する Wi-Fi 位置情報機能を使用して、付近にある RTT 対応の Wi-Fi アクセス ポイントや Wi-Fi Aware ピア デバイスとの距離を測定できます。

3 つ以上のアクセス ポイントまでの距離を測定する場合は、マルチラテレーション アルゴリズムを使用して、測定に最適なデバイスの位置を推定できます。結果の精度は通常 1~2 メートルの誤差の範囲内です。

この精度を確保できることによって、屋内ナビゲーション、明確な音声操作(例: 「このライトをつけて」)、位置情報をベースとする情報(例: 「このサービスに関してスペシャル オファーはありますか?」)などの精度の高い、位置情報を利用したサービスを開発できます。

リクエスト元のデバイスは、Wi-Fi RTT で距離を測定するためにアクセス ポイントに接続する必要はありません。プライバシー保護のため、リクエスト元のデバイスのみが アクセス ポイントまでの距離を判断します。アクセスポイントには 確認できます。Wi-Fi RTT オペレーションでは、フォアグラウンド アプリに対する制限はありませんが、バックグラウンド アプリに対しては制限が課されます。

Wi-Fi RTT と関連するファインタイム測定(FTM)機能は、以下のとおりです。 準拠していますWi-Fi RTT では、パケットがデバイス間を往復する時間を測定し、測定された時間に光速を乗じることによって 2 つのデバイス間の距離を計算するため、FTM による正確な時間測定が必要です。

Android 15(API レベル 35)で、IEEE 802.11az の非トリガーベースのサポートが導入されました (NTB)圏内です。

Android のバージョンに基づく実装の違い

Wi-Fi RTT は Android 9(API レベル 28)で導入されました。Android 9 搭載デバイスの場合、このプロトコルを使用してマルチラテレーションでデバイスの位置を特定するには、アプリが事前定義されたアクセス ポイント(AP)の位置情報データにアクセスする必要があります。このデータの保存方法や取得方法は任意に決定できます。

Android 10(API レベル 29)以降を搭載するデバイスでは、AP の位置情報データは緯度、経度、高度を含む ResponderLocation オブジェクトとして表すことができます。Location Configuration Information / Location Civic Report(LCI / LCR データ)をサポートする Wi-Fi RTT AP の場合、プロトコルは距離測定プロセス中に ResponderLocation オブジェクトを返します。

この機能を使用すると、アプリは事前にこの情報を保存する代わりに、AP に直接クエリを実行して位置を問い合わせることができます。そのため、ユーザーがある建物に初めて入ったときなど、AP を事前に把握できていない場合でも、アプリは AP を見つけてその位置を特定できます。

IEEE 802.11az NTB 距離測定のサポートは、Android 15 搭載デバイスで利用できます。 (API レベル 35)以降が必要です。つまり、デバイスが IEEE 802.11az をサポートしていれば NTB レスポンダー モード( WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_STA_RESPONDER), アプリは IEEE 802.11mc と IEEE 802.11az の両方に対応する AP を 使用します。RangingResult API は、情報提供のために拡張されました。 使用できる最小値と最大値についてです。 正確な間隔はアプリ側で制御することができます。

要件

  • 距離測定のリクエストを行うデバイスのハードウェアは、 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 を対象にしている場合は、 CANNOT TRANSLATE 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 に対応しているかどうかを確認するには、 PackageManager API:

Kotlin

context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)

Java

context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);

3. Wi-Fi RTT が利用可能かどうかを確認する

Wi-Fi RTT がデバイス上に存在していても、ユーザーが原因で利用できないことがあります。 Wi-Fi が無効になっています。ハードウェアやファームウェアの機能によっては、 SoftAP やテザリングを使用している場合、デバイスで Wi-Fi RTT がサポートされていないことがあります。確認するには Wi-Fi RTT が利用可能かどうか、 isAvailable()

Wi-Fi RTT の有効な状態は随時変わる可能性があります。アプリでは、 BroadcastReceiver 受け取り ACTION_WIFI_RTT_STATE_CHANGED、 在庫状況が変化したときに送信されます。ブロードキャスト インテントを受け取ったら、アプリは現在の状態を確認し、それに応じて動作を調整する必要があります。

次に例を示します。

Kotlin

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)

Java

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)が作成されます 接続先の AP または Wi-Fi Aware ピアのリストを指定して、 が要求されます。1 つの距離測定リクエストで複数のアクセス ポイントまたは Wi-Fi Aware ピアを指定すると、すべてのデバイスまでの距離が測定され、返されます。

たとえば、リクエストでは addAccessPoint() メソッドを使用して、距離を測定するアクセス ポイントを指定します。

Kotlin

val req: RangingRequest = RangingRequest.Builder().run {
    addAccessPoint(ap1ScanResult)
    addAccessPoint(ap2ScanResult)
    build()
}

Java

RangingRequest.Builder builder = new RangingRequest.Builder();
builder.addAccessPoint(ap1ScanResult);
builder.addAccessPoint(ap2ScanResult);

RangingRequest req = builder.build();

アクセス ポイントは、 ScanResult オブジェクト。これは、 使用して取得できます。 WifiManager.getScanResults()。 次を使用: addAccessPoints(List<ScanResult>) 複数のアクセス ポイントを一括で追加できます。

ScanResult オブジェクトには、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 プロトコルを使用して

同様に、圏内のリクエストでは、MAC アドレスまたは MAC アドレスを使用して Wi-Fi Aware ピアを追加できます。 アドレスまたはその PeerHandle addWifiAwarePeer(MacAddress peer) および addWifiAwarePeer(PeerHandle peer) あります。Wi-Fi Aware のピアの検出について詳しくは、 詳しくは、Wi-Fi Aware のドキュメントをご覧ください。

距離測定をリクエストする

アプリは、 WifiRttManager.startRanging() メソッドを呼び出し、次の内容を指定します。 RangingRequest: オペレーション、Executor で コールバック コンテキスト、 RangingResultCallback 結果を受け取ります。

例:

Kotlin

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) { … }
})

Java

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 結果のリストと一致する結果のリストとともに、 リクエストごとに 1 つの結果を返すことができます。結果の順序は、リクエストの順序と一致しない場合があります。距離測定オペレーションが完了した場合でも、各結果が依然として特定の測定の失敗を示している可能性がある点に留意してください。

距離測定の結果を解釈する

この関数から返される結果は、 onRangingResults コールバックが RangingResult で指定される 渡されます。各リクエストで、次の操作を行います。

1. リクエストを特定する

作成時に提供された情報に基づいてリクエストを識別します。 RangingRequest: ほとんどの場合、アクセスを識別する ScanResult で提供される MAC アドレスです。 ありますMAC アドレスは、距離測定の結果から getMacAddress() メソッドを呼び出します。

距離測定の結果のリストにおける並び順は、距離測定リクエストで指定されたピア(アクセス ポイント)とは異なる場合があるため、結果の順序ではなく MAC アドレスを使用してピアを特定する必要があります。

2. 各測定が成功したかどうかを判断する

測定が成功したかどうかを判断するには、 getStatus() メソッドを呼び出します。以外の値 STATUS_SUCCESS 失敗を示します。失敗は この結果のその他すべてのフィールドが (上記のリクエスト ID を除く)が無効で、対応する get* メソッドは次のエラーで失敗します。 IllegalStateException 例外。

3. 成功した各測定の結果を取得する

成功した測定(RangingResult)ごとに、結果を取得できます。 値をそれぞれの get メソッドに置き換えます。

  • 距離(mm)と測定の標準偏差:

    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()

で確認できます。

Wi-Fi-RTT 対応の Android デバイス

次の表に、スマートフォンアクセス ポイント小売店、倉庫、配送センターのデバイスの一覧を示します。 100 ミリ秒以内にサポートします。これらはごく一部を示したものです。ぜひ お問い合わせください RTT 対応プロダクトの一覧が表示されます。

アクセス ポイント

メーカーとモデル サポート日
Google Nest Wifi Pro(Wi-Fi 6E) サポート対象
Compulab WILD AP サポート対象
Google WiFi サポート対象
Google Nest Wifi ルーター サポート対象
Google Nest Wifi 拡張ポイント サポート対象
Aruba AP-635 サポート対象
Cisco 9130 サポート対象
Cisco 9136 サポート対象
Cisco 9166 サポート対象
Cisco 9164 サポート対象
Aruba AP-505 サポート対象
Aruba AP-515 サポート対象
Aruba AP-575 サポート対象
アルバ AP-518 サポート対象
Aruba AP-505H サポート対象
Aruba AP-565 サポート対象
Aruba AP-535 サポート対象

スマートフォン

メーカーとモデル Android バージョン
Google Pixel 6 9.0+
Google Pixel 6 Pro 9.0+
Google Pixel 5 9.0+
Google Pixel 5a 9.0+
Google Pixel 5a (5G) 9.0+
Xiaomi Mi 10 Pro 9.0+
Xiaomi Mi 10 9.0+
Xiaomi Redmi Mi 9T Pro 9.0+
Xiaomi Mi 9T 9.0+
Xiaomi Mi 9 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 Ultra 5G 9.0+
Samsung Galaxy S20 9.0+
Samsung Galaxy Note 10 以降 9.0+
Samsung Galaxy Note 10 5G 9.0+
Samsung Galaxy Note10 9.0+
Samsung A9 Pro 9.0+
Google Pixel 4 XL 9.0+
Google Pixel 4 9.0+
Google Pixel 4a 9.0+
Google Pixel 3 XL 9.0+
Google Pixel 3 9.0+
Google Pixel 3a XL 9.0+
Google Pixel 3a 9.0+
Google Pixel 2 XL 9.0+
Google Pixel 2 9.0+
Google Pixel 1 XL 9.0+
Google Pixel 1 9.0+
ポコ X2 9.0+
シャープ Aquos R3 SH-04L 9.0+

小売、倉庫、配送センターのデバイス

メーカーとモデル Android バージョン
ゼブラ PS20 10.0 以降
Zebra 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 以降
ゼブラ L10 10.0 以降
Zebra CC600/CC6000 10.0 以降
ゼブラ MC3300X 10.0 以降
ゼブラ MC330X 10.0 以降
ゼブラ TC52X 10.0 以降
ゼブラ TC57X 10.0 以降
Zebra EC50(LAN、HC) 10.0 以降
Zebra EC55(WAN) 10.0 以降
ゼブラ WT6300 10.0 以降
Skorpio X5 10.0 以降