Android 16에서는 기기 간의 정확한 측정을 위한 통합되고 표준화된 인터페이스를 제공하는 측정 모듈을 도입합니다. 이 API 노출 영역을 사용하면 각 측정 기술을 개별적으로 처리할 필요 없이 피어 기기의 거리와 위치를 측정할 수 있습니다.
측정 모듈은 다음 기술을 지원합니다.
- 초광대역
- 블루투스 채널 소리
- Wi-Fi NAN RTT
- 블루투스 RSSI 측정
범위 설정 기능 및 사용 가능 여부
RangingManager
클래스는 앱에 로컬 기기에서 지원하는 측정 기술에 관한 정보와 각 기술의 사용 가능 여부 및 기능을 제공합니다. 앱은 Callback
를 등록하여 지원되는 기술의 사용 가능 여부 또는 기능 변경에 관한 업데이트를 수신할 수 있습니다.
기기 역할
측정 세션에 참여하는 기기는 이니시에이터 또는 응답자여야 합니다. 시작 기기는 하나 이상의 응답자 기기로 측정 세션을 시작합니다. 응답자 기기는 한 번에 하나의 시작자만의 측정 거리 요청에 응답합니다. RangingPreference
클래스를 사용하여 측정 세션에서 특정 기기의 역할을 지정할 수 있습니다.
세션 유형 범위
기기 간에 측정 세션을 시작할 때는 세션의 매개변수를 교환하기 위해 부밴드 (OOB) 데이터 전송을 설정해야 하는 경우가 많습니다.
탐색 모듈은 OOB 협상을 처리할 수 있지만 맞춤 OOB 구현도 지원합니다.

기본 OOB 구현
이 세션 유형 (RANGING_SESSION_OOB
)에서는 탐색 모듈이 OOB 협상을 처리하여 탐색 세션을 시작합니다. 앱에서 제공하는 측정 범위 환경설정에 따라 적절한 매개변수를 선택하고 두 기기에서 지원하는 사항에 따라 적절한 기술을 사용합니다. 이 세션 유형은 표준화된 OOB specification
를 사용합니다.
측정 모듈은 피어 기기와 상호작용하는 데 사용할 OOB 데이터 형식과 시퀀스만 정의합니다. 피어 기기 검색 또는 연결 설정을 처리하지 않습니다.
맞춤 OOB 구현
이 세션 유형 (RANGING_SESSION_RAW
)에서 앱은 탐색 모듈의 OOB 흐름을 우회하고 자체 OOB 협상 및 매개변수를 처리합니다.
즉, 앱은 피어 기기가 지원하는 기술을 결정하고, 측정 범위 매개변수를 협상하고, 측정 범위 세션을 시작해야 합니다.
범위 설정
RangingPreference
객체를 사용하여 측정 세션에 원하는 매개변수를 지정합니다. 다음과 같은 상호작용에 반응합니다.
- 기기 역할 기기가 시작자인지 응답자인지 나타냅니다.
- 측정 범위 구성
RangingConfig
객체는 탐색 세션 유형과 탐색 세션을 시작하는 데 필요한 기타 매개변수를 지정합니다. - 세션 구성.
SessionConfig
객체는 측정 한도, 센서 융합, 지오펜스 구성 등 측정 세션에서 적용할 매개변수를 지정합니다.
범위 설정 권한
현재 및 향후의 모든 측정 기술에 액세스하려면 측정 모듈에 새로운 통합 권한(android.permission.RANGING
)이 필요합니다. 이 권한은 NEARBY_DEVICES_PERMISSIONS
목록에 있습니다.
<uses-permission android:name="android.permission.RANGING" />
제한
측정 모듈은 다음을 비롯한 여러 가지 이유로 측정을 제한할 수 있습니다.
- 서드 파티 앱은 지원되는 기기에서만 초광대역을 사용하여 백그라운드 측정을 실행할 수 있습니다. 다른 기술을 사용하여 백그라운드에서 측정 범위를 설정하는 것은 허용되지 않습니다.
- 기기당 최대 동시 측정 세션 수에 도달하면 측정이 허용되지 않습니다.
- 배터리, 성능, 메모리와 같은 시스템 상태 문제로 인해 측정 범위가 제한될 수 있습니다.
또한 측정 모듈에는 다음과 같은 알려진 제한사항이 있습니다.
- 측정 모듈은 초광대역의 경우 피어 기기에 대한 측정 데이터 전송만 지원합니다. 다른 기술의 경우 측정 모듈은 측정 데이터를 시작 기기만으로 전송합니다.
- 측정 모듈은 원시 측정 모드에서 기기의 동적 추가만 지원하며, 초광대역에서만 지원됩니다.
- 측정 모듈은 기본 OOB 구현의 일대다 초광대역 세션을 지원하지 않습니다. 여러 기기 핸들을 전달하면 모듈은 초광대역을 지원하는 각 피어 기기에 대해 일대일 세션을 만듭니다.
측정 세션 진행
Ranging 모듈을 사용하여 측정 세션을 실행하려면 다음 단계를 따르세요.
- 모든 기기가 Android 16 이상에서 작동하는지 확인합니다.
- 앱 매니페스트에서
android.permission.RANGING
권한을 요청합니다. - 측정 기술의 기능과 가용성을 평가합니다.
- 측정 작업을 위한 피어 기기를 찾습니다.
- 범위 설정 세션 유형에 설명된 세션 유형 중 하나를 사용하여 비표준 교환을 위한 연결을 설정합니다.
- 측정을 시작하고 측정 데이터를 연속적으로 획득합니다.
- 측정 세션을 종료합니다.
다음 코드 샘플은 이니시에이터 역할과 응답자 역할 모두에 대해 이러한 단계를 보여줍니다.
Kotlin
class RangingApp {
// Starts a ranging session on the initiator side.
fun startRangingInitiator(
context: Context,
deviceHandle: DeviceHandle,
executor: Executor,
callback: RangingSessionCallback
) {
// Get the RangingManager which is the entry point for ranging module.
val manager = context.getSystemService(RangingManager::class.java)
// Create a new RangingSession using the provided executor and callback.
val session = manager.createRangingSession(executor, callback)
// Create an OobInitiatorRangingConfig, which specifies the ranging parameters for
// the initiator role.
val config = OobInitiatorRangingConfig.Builder()
.setFastestRangingInterval(Duration.ofMillis(100))
.setSlowestRangingInterval(Duration.ofMillis(5000))
.setRangingMode(RANGING_MODE_AUTO)
.setSecurityLevel(SECURITY_LEVEL_BASIC)
.addDeviceHandle(deviceHandle)
.build()
// Create a RangingPreference, which specifies the role (initiator) and
// configuration for the ranging session.
val preference =
RangingPreference.Builder(DEVICE_ROLE_INITIATOR, config).build()
// Start ranging session.
session.start(preference)
// If successful, the ranging data will be sent through callback#onResults
// Stop ranging session
session.stop()
}
// Starts a ranging session on the responder side.
fun startRangingResponder(
context: Context,
deviceHandle: DeviceHandle,
executor: Executor,
callback: RangingSessionCallback
) {
// Get the RangingManager which is the entry point for ranging module.
val manager = context.getSystemService(RangingManager::class.java)
// Create a new RangingSession using the provided executor and callback.
val session = manager.createRangingSession(executor, callback)
// Create an OobResponderRangingConfig, which specifies the ranging parameters for
// the responder role.
val config = OobResponderRangingConfig.Builder(deviceHandle).build()
// Create a RangingPreference, which specifies the role (responder) and
// configuration for the ranging session.
val preference =
RangingPreference.Builder(DEVICE_ROLE_RESPONDER, config).build()
// Start the ranging session.
session.start(preference)
// Stop the ranging session
session.stop()
}
}
자바
public class RangingApp {
// Starts a ranging session on the initiator side.
void startRangingInitiator(Context context, DeviceHandle deviceHandle, Executor executor, RangingSessionCallback callback) {
// Get the RangingManager which is the entry point for ranging module.
RangingManager manager = context.getSystemService(RangingManager.class);
// Create a new RangingSession using the provided executor and callback.
RangingSession session = manager.createRangingSession(executor, callback);
// Create an OobInitiatorRangingConfig, which specifies the ranging parameters for
// the initiator role.
OobInitiatorRangingConfig config = new OobInitiatorRangingConfig.Builder()
.setFastestRangingInterval(Duration.ofMillis(100))
.setSlowestRangingInterval(Duration.ofMillis(5000))
.setRangingMode(RANGING_MODE_AUTO)
.setSecurityLevel(SECURITY_LEVEL_BASIC)
.addDeviceHandle(deviceHandle)
.build();
// Create a RangingPreference, which specifies the role (initiator) and
// configuration for the ranging session.
RangingPreference preference =
new RangingPreference.Builder(DEVICE_ROLE_INITIATOR, config).build();
// Start ranging session.
session.start(preference);
// If successful, the ranging data will be sent through callback#onResults
// Stop ranging session
session.stop();
}
// Starts a ranging session on the responder side.
void startRangingResponder(Context context, DeviceHandle deviceHandle, Executor executor, RangingSessionCallback callback) {
// Get the RangingManager which is the entry point for ranging module.
RangingManager manager = context.getSystemService(RangingManager.class);
// Create a new RangingSession using the provided executor and callback.
RangingSession session = manager.createRangingSession(executor, callback);
// Create an OobResponderRangingConfig, which specifies the ranging parameters for
// the responder role.
OobResponderRangingConfig config = new OobResponderRangingConfig.Builder( deviceHandle).build();
// Create a RangingPreference, which specifies the role (responder) and
// configuration for the ranging session.
RangingPreference preference =
new RangingPreference.Builder(DEVICE_ROLE_RESPONDER, config).build();
// Start the ranging session.
session.start(preference);
// Stop the ranging session
session.stop();
}
}
샘플 앱
측정 모듈을 사용하는 방법의 엔드 투 엔드 예는 AOSP의 샘플 앱을 참고하세요. 이 샘플 앱은 Ranging 모듈에서 지원하는 모든 측정 기술을 다루며 지원되는 두 세션 유형의 흐름을 포함합니다.