### Initialize and Start DL-TDoA Ranging Session in Android Source: https://developer.android.com/about/versions/17/features Demonstrates initializing the Ranging Manager, verifying UWB DL-TDoA support, and starting a ranging session. Requires Android SDK and UWB capabilities on the device. ```kotlin class RangingApp { fun initDlTdoa(context: Context) { // Initialize the Ranging Manager val rangingManager = context.getSystemService(RangingManager::class.java) // Register for device capabilities val capabilitiesCallback = object : RangingManager.CapabilitiesCallback { override fun onRangingCapabilities(capabilities: RangingCapabilities) { // Make sure Dl-TDoA is supported before starting the session if (capabilities.uwbCapabilities != null && capabilities.uwbCapabilities!!.isDlTdoaSupported) { startDlTDoASession(context) } } } rangingManager.registerCapabilitiesCallback(Executors.newSingleThreadExecutor(), capabilitiesCallback) } fun startDlTDoASession(context: Context) { // Initialize the Ranging Manager val rangingManager = context.getSystemService(RangingManager::class.java) // Create session and configure parameters val executor = Executors.newSingleThreadExecutor() val rangingSession = rangingManager.createRangingSession(executor, RangingSessionCallback()) val rangingRoundIndexes = intArrayOf(0) val config: ByteArray = byteArrayOf() // OOB config data val params = DlTdoaRangingParams.createFromFiraConfigPacket(config, rangingRoundIndexes) val rangingDevice = RangingDevice.Builder().build() val rawTagDevice = RawRangingDevice.Builder() .setRangingDevice(rangingDevice) .setDlTdoaRangingParams(params) .build() val dtTagConfig = RawDtTagRangingConfig.Builder(rawTagDevice).build() val preference = RangingPreference.Builder(DEVICE_ROLE_DT_TAG, dtTagConfig) .setSessionConfig(SessionConfig.Builder().build()) .build() // Start the ranging session rangingSession.start(preference) } } private class RangingSessionCallback : RangingSession.Callback { override fun onDlTdoaResults(peer: RangingDevice, measurement: DlTdoaMeasurement) { // Process measurement results here } } ``` ```java public class RangingApp { public void initDlTdoa(Context context) { // Initialize the Ranging Manager RangingManager rangingManager = context.getSystemService(RangingManager.class); // Register for device capabilities RangingManager.CapabilitiesCallback capabilitiesCallback = new RangingManager.CapabilitiesCallback() { @Override public void onRangingCapabilities(RangingCapabilities capabilities) { // Make sure Dl-TDoA is supported before starting the session if (capabilities.getUwbCapabilities() != null && capabilities.getUwbCapabilities().isDlTdoaSupported) { startDlTDoASession(context); } } }; rangingManager.registerCapabilitiesCallback(Executors.newSingleThreadExecutor(), capabilitiesCallback); } public void startDlTDoASession(Context context) { RangingManager rangingManager = context.getSystemService(RangingManager.class); // Create session and configure parameters Executor executor = Executors.newSingleThreadExecutor(); RangingSession rangingSession = rangingManager.createRangingSession(executor, new RangingSessionCallback()); int[] rangingRoundIndexes = new int[] {0}; byte[] config = new byte[0]; // OOB config data DlTdoaRangingParams params = DlTdoaRangingParams.createFromFiraConfigPacket(config, rangingRoundIndexes); RangingDevice rangingDevice = new RangingDevice.Builder().build(); RawRangingDevice rawTagDevice = new RawRangingDevice.Builder() .setRangingDevice(rangingDevice) .setDlTdoaRangingParams(params) .build(); RawDtTagRangingConfig dtTagConfig = new RawDtTagRangingConfig.Builder(rawTagDevice).build(); RangingPreference preference = new RangingPreference.Builder(DEVICE_ROLE_DT_TAG, dtTagConfig) .setSessionConfig(new SessionConfig.Builder().build()) .build(); // Start the ranging session rangingSession.start(preference); } private static class RangingSessionCallback implements RangingSession.Callback { @Override public void onDlTdoaResults(RangingDevice peer, DlTdoaMeasurement measurement) { // Process measurement results here } } } ``` -------------------------------- ### Configure compileSdk for Android 17 Source: https://developer.android.com/about/versions/17/setup-sdk Updates the build configuration to use the Android 17 preview SDK for compilation. This is required to access new APIs introduced in the Android 17 release. ```Groovy android { compileSdkPreview = "CinnamonBun" } ``` ```Kotlin android { compileSdkPreview = "CinnamonBun" } ``` -------------------------------- ### Define DL-TDoA OOB Configuration Data in Java Source: https://developer.android.com/about/versions/17/features Demonstrates the byte array structure required for Wi-Fi and BLE Out-of-Band (OOB) configurations for DL-TDoA ranging. These arrays contain headers, FiRa sub-elements, and session-specific parameters. ```java // Wifi Configuration byte[] wifiConfig = { (byte) 0xDD, (byte) 0x2D, (byte) 0x5A, (byte) 0x18, (byte) 0xFF, // Header (byte) 0x5F, (byte) 0x19, // FiRa Sub-Element (byte) 0x02, (byte) 0x00, // Profile ID (byte) 0x06, (byte) 0x02, (byte) 0x20, (byte) 0x08, // MAC Address (byte) 0x14, (byte) 0x01, (byte) 0x0C, // Preamble Index (byte) 0x27, (byte) 0x02, (byte) 0x08, (byte) 0x07, // Vendor ID (byte) 0x28, (byte) 0x06, (byte) 0xCA, (byte) 0xC8, (byte) 0xA6, (byte) 0xF7, (byte) 0x6F, (byte) 0x08, // Static STS IV (byte) 0x08, (byte) 0x02, (byte) 0x60, (byte) 0x09, // Slot Duration (byte) 0x1B, (byte) 0x01, (byte) 0x0A, // Slots per RR (byte) 0x09, (byte) 0x04, (byte) 0xE8, (byte) 0x03, (byte) 0x00, (byte) 0x00, // Duration (byte) 0x9F, (byte) 0x04, (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01 // Session ID }; // BLE Configuration byte[] bleConfig = { (byte) 0x2D, (byte) 0x16, (byte) 0xF4, (byte) 0xFF, // Header (byte) 0x5F, (byte) 0x19, // FiRa Sub-Element (byte) 0x02, (byte) 0x00, // Profile ID (byte) 0x06, (byte) 0x02, (byte) 0x20, (byte) 0x08, // MAC Address (byte) 0x14, (byte) 0x01, (byte) 0x0C, // Preamble Index (byte) 0x27, (byte) 0x02, (byte) 0x08, (byte) 0x07, // Vendor ID (byte) 0x28, (byte) 0x06, (byte) 0xCA, (byte) 0xC8, (byte) 0xA6, (byte) 0xF7, (byte) 0x6F, (byte) 0x08, // Static STS IV (byte) 0x08, (byte) 0x02, (byte) 0x60, (byte) 0x09, // Slot Duration (byte) 0x1B, (byte) 0x01, (byte) 0x0A, // Slots per RR (byte) 0x09, (byte) 0x04, (byte) 0xE8, (byte) 0x03, (byte) 0x00, (byte) 0x00, // Duration (byte) 0x9F, (byte) 0x04, (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01 // Session ID }; ```