Wi-Fi 위치: RTT를 사용한 범위 설정

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) 기능은 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를 찾고 그 위치를 알아낼 수 있습니다.

IEEE 802.11az NTB 범위 지원은 Android 15를 실행하는 기기에서 사용할 수 있습니다. (API 수준 35) 이상 즉, 기기에서 IEEE 802.11az를 지원하는 경우 NTB 응답자 모드( WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_STA_RESPONDER), 앱은 단일 IP 주소로 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_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를 사용 중지했습니다. 하드웨어와 펌웨어 기능에 따라 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);

자세한 내용은 브로드캐스트를 참조하세요.

범위 설정 요청 만들기

범위 설정 요청 (RangingRequest) 생성됨 특정 IP 범위를 사용하여 가 요청됩니다 한 번의 범위 설정 요청에서 여러 개의 액세스 포인트 또는 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 범위를 지원하는 기기는 802.11mc 또는 AP의 기능에 따라 802.11az 범위, AP는 둘 다 지원합니다. IEEE 802.11az를 지원하지 않는 기기는 IEEE 802.11mc 프로토콜을 사용하여 범위를 지정합니다.

마찬가지로 범위 설정 요청은 MAC 또는 MAC 주소를 사용하여 Wi-Fi Aware 동종 앱을 추가할 수 있습니다. 주소 또는 해당 PeerHandleaddWifiAwarePeer(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) { … }
})

자바

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: 대부분 액세스 권한을 식별하는 ScanResult에 제공된 MAC 주소 있습니다. MAC 주소는 getMacAddress() 드림 메서드를 사용하여 축소하도록 요청합니다.

범위 설정 결과의 목록은 범위 설정 요청에서 지정한 동종 앱(액세스 포인트)의 순서와 다를 수 있으므로 MAC 주소를 사용하여 결과의 순서가 아니라 동종 앱을 식별해야 합니다.

2. 각 측정이 성공했는지 확인

측정이 성공했는지 확인하려면 getStatus() 드림 메서드를 사용하여 축소하도록 요청합니다. 다음 값 이외의 값 STATUS_SUCCESS 드림 실패를 나타냅니다. 실패는 이 결과의 다른 모든 필드가 (위의 요청 식별 제외)이 유효하지 않으며, get* 메서드가 실패하고 IllegalStateException 예외가 있습니다.

3. 각 성공적인 측정에 대한 결과 가져오기

성공적인 측정 (RangingResult)마다 결과를 가져올 수 있습니다. 값을 각 get 메서드로 대체합니다.

를 통해 개인정보처리방침을 정의할 수 있습니다.

Wi-Fi RTT를 지원하는 Android 기기

다음 표에는 전화, 액세스 포인트, 소매, 창고, 유통 센터 기기가 나와 있습니다. Wi-Fi RTT를 지원하는 기기입니다. 많은 정보가 포함되어 있지 않습니다. 권장 사항: Google에 문의 를 참조하세요.

액세스 포인트

제조업체 및 모델 지원 날짜
Nest Wifi Pro (Wi-Fi 6E) 지원됨
Compulab WILD AP 지원됨
Google Wi-Fi 지원됨
Google Nest Wi-Fi 라우터 지원됨
Google Nest Wi-Fi 포인트 지원됨
아루바 AP-635 지원됨
시스코 9130 지원됨
시스코 9136 지원됨
시스코 9166 지원됨
시스코 9164 지원됨
아루바 AP-505 지원됨
아루바 AP-515 지원됨
아루바 AP-575 지원됨
아루바 AP-518 지원됨
아루바 AP-505H 지원됨
아루바 AP-565 지원됨
아루바 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+
삼성 Galaxy Note 10+ 5G 9.0+
삼성 Galaxy S20+ 5G 9.0+
삼성 Galaxy S20+ 9.0+
삼성 Galaxy S20 5G 9.0+
삼성 Galaxy S20 Ultra 5G 9.0+
삼성 Galaxy S20 9.0+
삼성 Galaxy Note 10+ 9.0+
삼성 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+
포코 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 이상
얼룩말 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 이상