초광대역 통신은 기기 간의 정확한 측정(위치를 10cm 정확도로 측정)에 중점을 둔 무선 기술입니다. 이 무선 기술은 단거리 측정에 낮은 에너지 밀도를 사용하고 무선 스펙트럼의 상당 부분에서 고대역폭 신호를 보낼 수 있습니다. UWB의 대역폭이 500MHz를 초과하거나 (또는 20% 의 대역폭 비율을 초과)
컨트롤러/시작자와 제어 대상/응답자 비교
UWB 통신은 두 기기 간에 발생하며, 하나는 컨트롤러이고 다른 하나는 제어 대상입니다. 컨트롤러는 두 기기가 공유할 복잡한 채널(UwbComplexChannel
)을 결정하고 이니시에이터이며, 제어 대상은 응답자입니다.
컨트롤러는 여러 컨트롤러를 처리할 수 있지만 컨트롤러는 단일 컨트롤러에만 구독할 수 있습니다. 컨트롤러/이니시에이터 구성과 제어 대상/응답자 구성이 모두 지원됩니다.
범위 매개변수
컨트롤러와 제어 대상은 서로를 식별하고 범위 설정 매개변수를 통신하여 범위 설정을 시작해야 합니다. 이 교환은 애플리케이션이 선택한 보안 비표준(OOB) 메커니즘(예: 저전력 블루투스(BLE))을 사용하여 구현하도록 둡니다.
범위 매개변수에는 로컬 주소, 복잡한 채널, 세션 키 등이 포함됩니다. 이러한 매개변수는 측정 세션이 종료된 후 회전하거나 변경될 수 있으며 측정을 다시 시작하려면 다시 통신해야 합니다.
백그라운드 반경 설정
백그라운드에서 실행되는 앱은 기기에서 지원하는 경우 UWB 측정 세션을 시작할 수 있습니다. 기기 기능을 확인하려면 RangingCapabilities
를 참고하세요.
앱이 백그라운드에서 실행 중일 때는 측정 보고를 수신하지 않습니다. 앱이 포그라운드로 이동하면 측정 보고를 수신합니다.
STS 구성
앱 또는 서비스는 스크램블된 타임스탬프 시퀀스 (STS)를 사용하여 각 세션의 세션 키를 프로비저닝합니다. 프로비저닝된 STS는 정적 STS 구성보다 안전합니다. 프로비저닝된 STS는 Android 14 이상을 실행하는 모든 UWB 지원 기기에서 지원됩니다.
위협 카테고리 | 정적 STS | 프로비저닝된 STS |
---|---|---|
공기: 수동 관찰자 | 완화됨 | 완화됨 |
Air: 신호 증폭 | 완화됨 | 완화됨 |
Air: 재전송/중계 공격 | 취약함 | 완화됨 |
프로비저닝된 STS의 경우:
프로비저닝된 STS를 지원하는
RangingParameters
에서uwbConfigType
를 사용합니다.sessionKeyInfo
필드에 16바이트 키를 제공합니다.
정적 STS의 경우:
정적 STS를 지원하는
RangingParameters
의uwbConfigType
를 사용합니다.sessionKeyInfo
필드에 8바이트 키를 제공합니다.
단계
UWB API를 사용하려면 다음 단계를 따르세요.
- Android 기기가 Android 12 이상을 실행하고
PackageManager#hasSystemFeature("android.hardware.uwb")
를 사용하여 UWB를 지원하는지 확인합니다. - IoT 기기와의 거리 측정인 경우 FiRa MAC 1.3을 준수하는지 확인합니다.
BluetoothLeScanner
와 같은 선택한 OOB 메커니즘을 사용하여 UWB 지원 피어 기기를 찾습니다.- 선택한 보안 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 지원
이제 Java 클라이언트와의 상호 운용성을 달성하는 데 도움이 되는 Rxjava3 지원을 사용할 수 있습니다. 이 라이브러리는 측정 결과를 Observable 또는 Flowable 스트림으로 가져오고 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 지원 휴대기기
2025년 1월부터 다음 기기에서 Android UWB Jetpack 라이브러리가 지원됩니다.
공급업체 | 기기 모델 |
---|---|
Pixel Pro (6 Pro 이상), Fold, Tablet | |
Motorola | Edge 50 Ultra |
삼성 | Galaxy Note 20, Galaxy Plus 및 Ultra (S21 이상), Galaxy Z Fold (Fold2 이상) |
참고: 백그라운드 UWB 측정은 다음을 제외한 모든 기기에서 지원됩니다.
- Pixel 6 Pro 및 Pixel 7 Pro
- Android 13 이하를 실행하는 삼성 휴대전화
- Android 14 이하를 실행하는 삼성 중국 휴대전화
서드 파티 SDK
2023년 4월부터 이러한 파트너 솔루션은 현재 Jetpack 라이브러리와 호환됩니다.
- Estimote UWB 개발 키트
- 모바일 지식 MK UWB 키트 모바일 버전 2.0
알려진 문제: MAC 주소 및 정적 STS 공급업체 ID 필드의 바이트 순서가 반전됨
Android 13 이하에서는 Android UWB 스택이 다음 필드의 바이트 순서를 잘못 반전합니다.
- 기기 MAC 주소
- 대상 MAC 주소
- 정적 STS 공급업체 ID
Android 스택이 이러한 필드를 배열이 아닌 값으로 처리하기 때문에 바이트 순서가 반전됩니다. Google은 FiRa와 협력하여 이러한 필드를 배열로 취급해야 한다고 명시적으로 명시하도록 UCI 사양(CR-1112)을 업데이트하고 있습니다.
이 문제는 2320XXXX
출시의 GMS Core 업데이트를 통해 해결될 예정입니다.
그때부터 Android 기기를 준수하려면 IOT 공급업체가 이러한 필드의 바이트 순서가 역전되지 않도록 구현을 수정해야 합니다.