超寬頻通訊是一種無線電技術,可精確進行測距 (以 10 公分的精確度測量裝置之間的距離)。 這項無線電技術可使用低功耗密度進行短程測量 並執行高頻寬訊號 UWB 的頻寬超過 500 MHz (或超過 20% 小數) 頻寬)。
控管者/發起人與受控者/作答者
UWB 會在兩部裝置間通訊,其中一部是控制器,
另一個是控制人員控制器會決定複雜的管道
(UwbComplexChannel
)。
這兩個裝置會共用,發起人為發起者,「控制者」則是
作答者。
一個控制器可以處理多位受控者,但受控者只能訂閱 單一控制器控管者/發起人和受控者/作答者 設定檔
範圍參數
控管者和控制人員必須識別彼此並相互溝通 計算範圍參數。應用程式就會交由應用程式交換 採用自選的架構外安全機制 (OOB) 機制,例如 藍牙低功耗 (BLE)。
範圍參數 包括本機地址、複雜頻道和工作階段金鑰等等注意事項 這些參數可能會在測距工作階段結束後旋轉或以其他方式變更 並且需要重新通訊才能重新開始範圍。
背景範圍
在背景中執行的應用程式可在裝置中啟動 UWB 測距工作階段
但 AI 會支援該執行緒。如要查看裝置功能,請參閱 RangingCapabilities
。
應用程式在背景執行時不會收到精細報表。應用程式 等到應用程式移至前景時,就會收到詳盡的報表。
STS 設定
應用程式或服務使用亂碼,為每個工作階段佈建工作階段金鑰 時間戳記順序 (STS)。佈建的 STS 比靜態 STS 更安全 此外還會從 0 自動調整資源配置 您完全不必調整資源調度設定所有支援 UWB 的裝置皆支援已佈建的 STS 搭載 Android 14 以上版本。
威脅類別 | 靜態 STS | 提議的 STS |
---|---|---|
空氣:被動觀察器 | 已緩解 | 已緩解 |
空氣:訊號擴大 | 已緩解 | 已緩解 |
空氣:重播/重播攻擊 | 容易 | 已緩解 |
已佈建的 STS:
在支援已佈建 STS 的
RangingParameters
中使用uwbConfigType
。在
sessionKeyInfo
欄位中提供 16 位元組的金鑰。
靜態 STS:
在支援靜態 STS 的
RangingParameters
中使用uwbConfigType
。在
sessionKeyInfo
欄位中提供 8 位元組的金鑰。
操作步驟
如要使用 UWB API,請按照下列步驟操作:
- 確保 Android 裝置搭載 Android 12 以上版本,並
支援 UWB
PackageManager#hasSystemFeature("android.hardware.uwb")
。 - 如要對 IoT 裝置進行傳輸,請確認這些裝置為 FiRa MAC 1.3 確保符合規定
- 透過您選擇的 OOB 機制探索支援 UWB 的對等互連裝置。
例如
BluetoothLeScanner
。 - 使用您選擇的安全 OOB 機制交換參數。
例如
BluetoothGatt
。 - 如果使用者想停止工作階段,請取消工作階段範圍。
使用限制
使用 UWB API 時須遵守下列限制:
- 啟動新的 UWB 測距工作階段的應用程式必須是前景 應用程式或服務,除非上述圖表不支援背景測距功能
- 當應用程式移至背景 (工作階段執行期間) 時,應用程式 可能就不會繼續收到精細報表UWB 工作階段 都會繼續維持在較低層當應用程式回到 系統就會繼續分析取樣報表
程式碼範例
範例應用程式
如需 UWB Jetpack 程式庫的端對端範例,請參閱 GitHub 上的範例應用程式。此範例應用程式說明如何在 Android 裝置上驗證 UWB 相容性、使用 OOB 機制啟用探索程序,以及設定在兩部支援 UWB 的裝置間設定 UWB。此外,此範例也涵蓋了裝置控制和媒體分享的用途。
UWB 量表
以下程式碼範例會啟動和終止受控人的 UWB 範圍:
// The coroutineScope responsible for handling uwb ranging.
// This will be initialized when startRanging is called.
var job: Job?
// A code snippet that initiates uwb ranging for a Controlee.
suspend fun startRanging() {
// Get the ranging parameter of a partnering Controller using an OOB mechanism of choice.
val partnerAddress : Pair<UwbAddress, UwbComplexChannel> = listenForPartnersAddress()
// Create the ranging parameters.
val partnerParameters = RangingParameters(
uwbConfigType = UwbRangingParameters.UWB_CONFIG_ID_1,
// SessionKeyInfo is used to encrypt the ranging session.
sessionKeyInfo = null,
complexChannel = partnerAddress.second,
peerDevices = listOf(UwbDevice.createForAddress(partnerAddress.first)),
updateRateType = UwbRangingParameters.RANGING_UPDATE_RATE_AUTOMATIC
)
// Initiate a session that will be valid for a single ranging session.
val clientSession = uwbManager.clientSessionScope()
// Share the localAddress of the current session to the partner device.
broadcastMyParameters(clientSession.localAddress)
val sessionFlow = clientSession.prepareSession(partnerParameters)
// Start a coroutine scope that initiates ranging.
CoroutineScope(Dispatchers.Main.immediate).launch {
sessionFlow.collect {
when(it) {
is RangingResultPosition -> doSomethingWithPosition(it.position)
is RangingResultPeerDisconnected -> peerDisconnected(it)
}
}
}
}
// A code snippet that cancels uwb ranging.
fun cancelRanging() {
// Canceling the CoroutineScope will stop the ranging.
job?.let {
it.cancel()
}
}
RxJava3 支援
現已支援 Rxjava3 來協助實現與 Java 的互通性 用戶端。這個程式庫可讓您以可觀察或 可 Flow 串流,以及將 UwbClientSessionScope 擷取為單一物件。
private final UwbManager uwbManager;
// Retrieve uwbManager.clientSessionScope as a Single object
Single<UwbClientSessionScope> clientSessionScopeSingle =
UwbManagerRx.clientSessionScopeSingle(uwbManager);
UwbClientSessionScope uwbClientSessionScope = clientSessionScopeSingle.blockingGet();
// Retrieve uwbClientSessionScope.prepareSession Flow as an Observable object
Observable<RangingResult> rangingResultObservable =
UwbClientSessionScopeRx.rangingResultsObservable(clientSessionScope,
rangingParameters);
// Consume ranging results from Observable
rangingResultObservable.subscribe(
rangingResult -> doSomethingWithRangingResult(result), // onNext
(error) -> doSomethingWithError(error), // onError
() -> doSomethingOnResultEventsCompleted(), //onCompleted
);
// Unsubscribe
rangingResultObservable.unsubscribe();
// Retrieve uwbClientSessionScope.prepareSession Flow as a Flowable object
Flowable<RangingResult> rangingResultFlowable =
UwbClientSessionScopeRx.rangingResultsFlowable(clientSessionScope,
rangingParameters);
// Consume ranging results from Flowable using Disposable
Disposable disposable = rangingResultFlowable
.delay(1, TimeUnit.SECONDS)
.subscribeWith(new DisposableSubscriber<RangingResult> () {
@Override public void onStart() {
request(1);
}
@Override public void onNext(RangingResult rangingResult) {
doSomethingWithRangingResult(rangingResult);
request(1);
}
@Override public void onError(Throwable t) {
t.printStackTrace();
}
@Override public void onComplete() {
doSomethingOnEventsCompleted();
}
});
// Stop subscription
disposable.dispose();
支援生態系統
以下列出支援的合作夥伴裝置和第三方 SDK。
支援 UWB 的行動裝置
自 2024 年 3 月起,以下裝置支援 Android UWB Jetpack 程式庫:
供應商 | 裝置型號 |
---|---|
Pixel 6 Pro、7 Pro、8 Pro、Pixel Fold、平板電腦 | |
Samsung | Galaxy Note 20、S21+、S22+、S23+、S24+ Z Fold 2、3、4、5 |
第三方 SDK
自 2023 年 4 月起,這些合作夥伴解決方案與 新版 Jetpack 程式庫。
- Estimote UWB 開發套件。
- Mobile Knowledge MK UWB Kit Mobile Edition 2.0。
已知問題:對 MAC 位址和靜態 STS 供應商 ID 欄位反向的位元組順序
在 Android 13 以下版本中,Android UWB 堆疊會錯誤反轉位元組 排序以下欄位:
- 裝置的 MAC 位址
- 目標 MAC 位址
- 靜態 STS 供應商 ID
系統會撤銷位元組順序,因為 Android 堆疊會處理這些欄位 而非陣列我們正與 FiRa 合作更新 UCI 規格 (CR-1112)。 明確指出這些欄位應視為陣列。
這個問題將透過 2320XXXX
版本中的 GMS Core 更新修正。
之後,IoT 供應商必須修改 Android 裝置才能與 Android 裝置相容
以避免對這些欄位的位元組順序反轉。