Wi-Fi 位置:範圍涵蓋即時文字訊息

您可以使用 Wi-Fi RTT (往返時間) API 提供的 Wi-Fi 定位功能,測量與鄰近 RTT 支援 Wi-Fi 存取點和對等 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) 導入了對 IEEE 802.11az 非觸發式 (NTB) 測距的支援。

根據 Android 版本實作的差異

Wi-Fi RTT 是在 Android 9 (API 級別 28) 中導入。使用這個通訊協定,透過多點定位技術判斷搭載 Android 9 的裝置位置時,您必須在應用程式中存取預先決定的存取點 (AP) 位置資料。至於如何儲存及擷取這項資料,則由您自行決定。

在搭載 Android 10 (API 級別 29) 以上版本的裝置上,AP 位置資料可以表示為 ResponderLocation 物件,包括緯度、經度和海拔高度。對於支援位置設定資訊/位置公民報告 (LCI/LCR 資料) 的 Wi-Fi RTT AP,通訊協定會在測距程序期間傳回 ResponderLocation 物件。

這項功能可讓應用程式直接查詢 AP 的位置,而不必預先儲存這項資訊。因此,即使 AP 先前不明,應用程式也能找到 AP 並判斷其位置,例如使用者進入新建築物時。

搭載 Android 15 (API 級別 35) 以上版本的裝置支援 IEEE 802.11az NTB 測距。也就是說,如果裝置支援 IEEE 802.11az NTB 啟動器模式 (以 WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR 表示),應用程式就能透過單一範圍要求,找到支援 IEEE 802.11mc 和 IEEE 802.11az 的 AP。RangingResult API 已擴充,可提供可用於測距測量間隔的最小值和最大值相關資訊,讓應用程式控制確切間隔。

需求條件

  • 提出測距要求的裝置硬體必須實作 802.11-2016 FTM 標準或 802.11az 標準 (非觸發式測距)。
  • 提出測距要求的裝置必須搭載 Android 9 (API 級別 28) 以上版本。搭載 Android 15 (API 級別 35) 以上版本的裝置會啟用 IEEE 802.11az 非觸發式測距功能。
  • 提出測距要求的裝置必須啟用定位服務,並開啟 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_DEVICESACCESS_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 後,可能就無法使用。視硬體和韌體功能而定,部分裝置可能無法支援 Wi-Fi RTT,如果使用 SoftAP 或網路共用功能,如要查看 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 對等互連裝置清單。您可以在單一測距要求中指定多個存取點或 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()) 支援的 AP。支援 IEEE 802.11az NTB 測距的裝置會根據 AP 的功能執行 802.11mc 或 802.11az 測距,如果 AP 同時支援這兩種測距方式,則預設為 802.11az。不支援 IEEE 802.11az 的裝置會使用 IEEE 802.11mc 通訊協定執行所有測距作業。

同樣地,測距要求可以使用 MAC 位址或 PeerHandle,分別使用 addWifiAwarePeer(MacAddress peer)addWifiAwarePeer(PeerHandle peer) 方法,新增 Wi-Fi Aware 對等互連裝置。如要進一步瞭解如何探索 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 回呼,並傳回與要求清單相符的結果清單,每個要求對應一個結果。結果順序不一定與要求順序相符。請注意,測距作業可能會完成,但每個結果仍可能指出該特定測量作業失敗。

解讀測距結果

onRangingResults 回呼傳回的每個結果都會由 RangingResult 物件指定。針對每項要求執行下列操作。

1. 找出要求

根據建立要求時提供的資訊識別要求RangingRequest:通常是存取點識別資訊中提供的 MAC 位址。ScanResult您可以使用 getMacAddress() 方法,從測距結果取得 MAC 位址。

測距結果清單的順序可能與測距要求中指定的對等互連裝置 (存取點) 不同,因此您應使用 MAC 位址識別對等互連裝置,而非結果順序。

2. 判斷各項測量是否成功

如要判斷測量是否成功,請使用 getStatus() 方法。如果傳送的是 STATUS_SUCCESS 以外的任何值,則代表失敗。如果失敗,表示這項結果的所有其他欄位 (上述要求 ID 除外) 均無效,且對應的 get* 方法會因 IllegalStateException 例外狀況而失敗。

3. 取得每次成功評估的結果

每次成功評估 (RangingResult) 後,您都可以使用對應的 get 方法擷取結果值:

支援 Wi-Fi RTT 的 Android 裝置

下表列出支援 Wi-Fi RTT 的部分手機存取點,以及零售、倉儲和配送中心裝置。這些只是部分範例,建議你與我們聯絡,在此列出支援 RTT 的產品。

存取點

製造商和型號 支援日期 通訊協定
Nest Wifi Pro (Wi-Fi 6E) 支援 mc
Compulab WILD AP 支援 mc
Google Wi-Fi 支援 mc
Google Nest Wifi 路由器 支援 mc
Google Nest Wifi Point 支援 mc
Aruba AP-635 支援 mc
Cisco 9130 支援 mc
Cisco 9136 支援 mc
Cisco 9166 支援 mc
Cisco 9164 支援 mc
Cisco CW9172I 支援 mc/az
Cisco CW9172H 支援 mc/az
Cisco CW9176I 支援 mc/az
Cisco CW9178I 支援 mc/az
Aruba AP-505 支援 mc
Aruba AP-515 支援 mc
Aruba AP-575 支援 mc
Aruba AP-518 支援 mc
Aruba AP-505H 支援 mc
Aruba AP-565 支援 mc
Aruba AP-535 支援 mc
Aruba AP567 支援 mc
Aruba AP577 支援 mc
Aruba AP555 支援 mc
Aruba AP635 支援 mc
Aruba AP655 支援 mc
Aruba AP615 支援 mc
Aruba AP734 支援 mc/az
Aruba AP735 支援 mc/az
Aruba AP754 支援 mc/az
Aruba AP755 支援 mc/az

手機

製造商和型號 Android 版本
Google Pixel 9 Pro XL 14+
Google Pixel 9 14+
Google Pixel 9 Pro 14+
Google Pixel 9 Pro XL 14+
Google Pixel 7a 14+
Google Pixel 7 14+
Google Pixel 8 14+
Google Pixel 8 Pro 14+
Google Pixel 8a 14+
Samsung SM-S918B 14+
Samsung SM-A515F 14+
Google Pixel 9 Pro 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 Pixel 9 14+
Samsung SM-A127F 14+
Google Pixel 7 Pro 14+
Samsung SM-A556E 14+
Pixel 6 9.0 以上版本
Pixel 6 Pro 9.0 以上版本
Pixel 5 9.0 以上版本
Pixel 5a 9.0 以上版本
Pixel 5a (5G) 9.0 以上版本
小米 Mi 10 Pro 9.0 以上版本
小米 Mi 10 9.0 以上版本
小米 Redmi Mi 9T Pro 9.0 以上版本
小米 Mi 9T 9.0 以上版本
小米 Mi 9 9.0 以上版本
小米 Mi Note 10 9.0 以上版本
小米 Mi Note 10 Lite 9.0 以上版本
小米 Redmi Note 9S 9.0 以上版本
小米 Redmi Note 9 Pro 9.0 以上版本
小米 Redmi Note 8T 9.0 以上版本
小米 Redmi Note 8 9.0 以上版本
小米 Redmi K30 Pro 9.0 以上版本
Xiaomi Redmi K20 Pro 9.0 以上版本
小米 Redmi K20 9.0 以上版本
小米 Redmi Note 5 Pro 9.0 以上版本
小米 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 Note 10 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 以上版本
Poco X2 9.0 以上版本
Sharp Aquos R3 SH-04L 9.0 以上版本

零售、倉儲和配送中心裝置

製造商和型號 Android 版本
Zebra PS20 10.0 以上版本
Zebra TC52/TC52HC 10.0 以上版本
Zebra TC57 10.0 以上版本
Zebra TC72 10.0 以上版本
Zebra TC77 10.0 以上版本
Zebra MC93 10.0 以上版本
Zebra TC8300 10.0 以上版本
Zebra VC8300 10.0 以上版本
Zebra EC30 10.0 以上版本
Zebra ET51 10.0 以上版本
Zebra ET56 10.0 以上版本
Zebra L10 10.0 以上版本
Zebra CC600/CC6000 10.0 以上版本
Zebra MC3300x 10.0 以上版本
Zebra MC330x 10.0 以上版本
Zebra TC52x 10.0 以上版本
Zebra TC57x 10.0 以上版本
Zebra EC50 (LAN 和 HC) 10.0 以上版本
Zebra EC55 (WAN) 10.0 以上版本
Zebra WT6300 10.0 以上版本
Skorpio X5 10.0 以上版本