Wi-Fi RTT(Round-Trip-Time) API가 제공하는 Wi-Fi 위치 기능을 사용하여 주변의 RTT 지원 Wi-Fi 액세스 포인트 및 동종 앱 Wi-Fi Aware 기기와의 거리를 측정할 수 있습니다.
기기에서 3개 이상의 액세스 지점에 대한 거리를 측정하는 경우, 다변측정(MLAT) 알고리즘을 사용하여 해당 측정에 가장 적합한 기기 위치를 측정할 수 있습니다. 일반적으로 결과의 정확도는 1~2m 이내입니다.
이 정도의 정확도에서는 세밀한 위치 기반 서비스를 개발할 수 있습니다. 예를 들어 실내 탐색, 명확한 음성 제어(예: '조명 켜기'), 위치 기반 정보(예: '이 제품 관한 특별 이벤트가 있는지 여부')가 있습니다.
요청하는 기기는 Wi-Fi RTT와의 거리를 측정하기 위해 액세스 포인트에 연결하지 않아도 됩니다. 개인 정보 보호를 위해 요청하는 기기에서만 액세스 포인트에 대한 거리를 측정할 수 있으며 액세스 포인트에는 이 정보가 없습니다. Wi-Fi RTT 작업은 포그라운드 앱에 관한 제한이 없지만 백그라운드 앱 사용이 제한됩니다.
Wi-Fi RTT 및 관련 FTM (Fine-Time-Measurement) 기능은 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
객체로 표시될 수 있으며 여기에는 위도, 경도, 고도가 포함됩니다. 위치 구성 정보/위치 시민 보고(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_NTB_INITIATOR
로 표시됨)를 지원하는 경우 앱은 단일 범위 요청으로 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 검색을 켜야 합니다.(Settings > Location)
- 측정 요구를 실행하는 앱이 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를 지원하는지 확인하려면 다음과 같은 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)
자바
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);
자세한 내용은 브로드캐스트를 참조하세요.
범위 설정 요청 만들기
범위를 요청하는 AP 또는 Wi-Fi 인식 피어의 목록을 지정하여 범위 설정 요청(RangingRequest
)을 생성합니다. 한 번의 범위 설정 요청에서 여러 개의 액세스 포인트 또는 Wi-Fi Aware 동종 앱을 지정할 수 있습니다. 이 경우, 모든 기기와의 거리를 측정해서 반환합니다.
예를 들어 요청에서 addAccessPoint()
메서드를 사용하여 거리를 측정할 액세스 포인트를 지정할 수 있습니다.
Kotlin
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
객체는 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 인식 피어를 추가할 수 있습니다. 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) { … } })
자바
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
의 콜백 중 하나로 반환됩니다.
- 전체 범위 설정 작업이 실패하면
RangingResultCallback
에 설명된 상태 코드와 함께onRangingFailure
콜백이 트리거됩니다. 서비스가 그 시점에 범위 설정 작업을 실행할 수 없을 경우 이런 실패가 발생할 수 있습니다. 예를 들어 Wi-Fi가 비활성화되었거나, 애플리케이션이 너무 많은 범위 설정 작업을 요청해서 사용이 제한되었거나, 권한에 문제가 있는 것이 원인일 수 있습니다. - 범위 설정 작업이 완료되면 요청의 목록과 일치하는 결과 목록(요청당 1개)과 함께
onRangingResults
콜백이 트리거됩니다. 결과의 순서는 요청의 순서와 반드시 일치하지는 않습니다. 범위 설정 작업이 완료되더라도 각 결과에서 특정 측정이 실패한 것으로 나타날 수 있습니다.
범위 설정 결과 해석
onRangingResults
콜백이 반환하는 각각의 결과는 RangingResult
객체로 지정됩니다. 각 요청에 관해 다음을 실행합니다.
1. 요청 식별
RangingRequest
를 생성할 때 제공된 정보에 기초하여 요청을 식별합니다. 일반적으로 액세스 포인트를 식별하는 ScanResult
에 제공된 MAC 주소입니다. MAC 주소는 getMacAddress()
메서드를 사용하여 범위 설정 결과에서 얻을 수 있습니다.
범위 설정 결과의 목록은 범위 설정 요청에서 지정한 동종 앱(액세스 포인트)의 순서와 다를 수 있으므로 MAC 주소를 사용하여 결과의 순서가 아니라 동종 앱을 식별해야 합니다.
2. 각 측정이 성공했는지 확인
측정이 성공했는지 확인하려면 getStatus()
메서드를 사용합니다. STATUS_SUCCESS
이외의 모든 값은 실패를 나타냅니다. 실패는 이 결과를 제외한 다른 모든 필드(위의 요청 식별 제외)가 무효이고 이 get*
메서드가 IllegalStateException
예외와 함께 실패한다는 것을 의미합니다.
3. 각 성공적인 측정에 대한 결과 가져오기
각 성공적인 측정 (RangingResult
)에 대해 각 get
메서드로 결과 값을 검색할 수 있습니다.
거리(mm)와 측정값의 표준 편차:
측정에 사용된 RSSI:
측정을 실시한 시간(ms)(부팅 이후부터의 시간):
시도한 측정 횟수 및 성공한(거리 측정값의 기초가 되는) 측정 횟수:
클라이언트 기기가 11az NTB 측정 간에 기다려야 하는 최소 시간 및 최대 시간입니다.
getMinTimeBetweenNtbMeasurementsMicros()
및getMaxTimeBetweenNtbMeasurementsMicros()
는 최소 시간과 최대 시간을 반환합니다. 최소 시간이 경과하기 전에 다음 측정 측정이 요청되면 API는 캐시된 측정 결과를 반환합니다. 최대 시간이 경과한 후에 다음 측정 측정이 요청되면 API는 트리거되지 않은 측정 세션을 종료하고 응답하는 관측소와 새 측정 세션을 협상합니다. 새 측정 세션을 요청하면 측정 시간에 오버헤드가 추가되므로 새 측정 세션을 요청해서는 안 됩니다. 802.11az 비트리거 기반 측정 효율을 최대한 활용하려면 이전RangingResult
측정에 지정된 최소 측정 시간과 최대 측정 시간 사이에서 다음 측정 요청을 트리거합니다.응답자 및 이니시에이터 스테이션이 IEEE 802.11az NTB 결과의 프 preamble에 사용한 긴 트레인 필드 (LTF) 반복:
IEEE 802.11az NTB 결과에 대해 시작 스테이션에서 사용한 전송 및 수신 공간 시간 스트림 (STS) 수입니다.
Wi-Fi RTT를 지원하는 Android 기기
다음 표에는 WiFi-RTT를 지원하는 일부 휴대전화, 액세스 포인트, 소매업체, 창고, 배송 센터 기기가 나와 있습니다. 많은 정보가 포함되어 있지 않습니다. Google에 문의하여 RTT 사용이 가능한 제품의 목록을 알아보세요.
액세스 포인트
제조업체 및 모델 | 지원 날짜 |
---|---|
Nest Wifi Pro (Wi-Fi 6E) | 지원됨 |
Compulab WILD AP | 지원됨 |
Google Wi-Fi | 지원됨 |
Google Nest Wi-Fi 라우터 | 지원됨 |
Google Nest Wi-Fi 포인트 | 지원됨 |
Aruba AP-635 | 지원됨 |
Cisco 9130 | 지원됨 |
Cisco 9136 | 지원됨 |
Cisco 9166 | 지원됨 |
Cisco 9164 | 지원됨 |
Aruba AP-505 | 지원됨 |
Aruba AP-515 | 지원됨 |
Aruba AP-575 | 지원됨 |
Aruba AP-518 | 지원됨 |
Aruba AP-505H | 지원됨 |
Aruba AP-565 | 지원됨 |
Aruba AP-535 | 지원됨 |
휴대전화
제조업체 및 모델 | Android 버전 |
---|---|
Pixel 6 | 9.0+ |
Pixel 6 Pro | 9.0+ |
Pixel 5 | 9.0+ |
Pixel 5a | 9.0+ |
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+ |
삼성 Galaxy S20+ 5G | 9.0+ |
Samsung Galaxy S20+ | 9.0+ |
Samsung Galaxy S20 5G | 9.0+ |
삼성 Galaxy S20 Ultra 5G | 9.0+ |
Samsung Galaxy S20 | 9.0+ |
삼성 갤럭시 Note 10+ | 9.0+ |
Samsung Galaxy Note 10 5G | 9.0+ |
Samsung Galaxy Note 10 | 9.0+ |
삼성 A9 프로 | 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 이상 |