डिवाइसों के बीच की रेंज

Android 16 में रेंजिंग मॉड्यूल पेश किया गया है. यह मॉड्यूल, डिवाइसों के बीच सटीक रेंजिंग के लिए एक जैसा और स्टैंडर्ड इंटरफ़ेस उपलब्ध कराता है. इस एपीआई की मदद से, आस-पास मौजूद डिवाइसों की दूरी और उनकी पोज़िशन का पता लगाया जा सकता है. इसके लिए, आपको हर रेंजिंग टेक्नोलॉजी को अलग-अलग मैनेज करने की ज़रूरत नहीं होती.

रेंजिंग मॉड्यूल, इन टेक्नोलॉजी के साथ काम करता है:

रेंजिंग की सुविधाएं और उपलब्धता

RangingManager क्लास, ऐप्लिकेशन को स्थानीय डिवाइस पर काम करने वाली रेंजिंग टेक्नोलॉजी के बारे में जानकारी देती है. साथ ही, यह हर टेक्नोलॉजी की उपलब्धता और क्षमताओं के बारे में भी जानकारी देती है. ऐप्लिकेशन, Callback के लिए रजिस्टर कर सकते हैं. इससे उन्हें, काम करने वाली किसी भी टेक्नोलॉजी की उपलब्धता या क्षमताओं में होने वाले बदलावों के बारे में अपडेट मिल सकेंगे.

डिवाइस की भूमिकाएं

रेंजिंग सेशन में हिस्सा लेने वाले डिवाइस को शुरू करने वाला या जवाब देने वाला होना चाहिए. रेंजिंग सेशन शुरू करने वाला डिवाइस, एक या उससे ज़्यादा रेस्पॉन्डर डिवाइसों के साथ रेंजिंग सेशन शुरू करता है. जवाब देने वाला डिवाइस, एक समय में सिर्फ़ एक डिवाइस से रेंजिंग के अनुरोधों का जवाब देता है. RangingPreference क्लास की मदद से, रेंजिंग सेशन में किसी डिवाइस की भूमिका तय की जा सकती है.

सेशन के अलग-अलग टाइप

डिवाइसों के बीच रेंजिंग सेशन शुरू करते समय, सेशन के लिए पैरामीटर का आदान-प्रदान करने के लिए, अक्सर आउट-ऑफ़-बैंड (ओओबी) डेटा ट्रांसपोर्ट सेट अप करना ज़रूरी होता है.

रेंजिंग मॉड्यूल, आपके लिए ओओबी नेगोशिएशन को मैनेज कर सकता है. हालांकि, यह कस्टम ओओबी लागू करने की सुविधा भी देता है.

पहली इमेज. सेशन टाइप के लिए ओओबी फ़्लो.

OOB को डिफ़ॉल्ट रूप से लागू करना

इस सेशन टाइप (RANGING_SESSION_OOB) में, रेंजिंग मॉड्यूल, रेंजिंग सेशन शुरू करने के लिए OOB नेगोशिएशन को हैंडल करता है. यह ऐप्लिकेशन की ओर से दी गई रेंजिंग की प्राथमिकताओं के आधार पर, सही पैरामीटर चुनता है. साथ ही, यह उन टेक्नोलॉजी का इस्तेमाल करता है जो दोनों डिवाइसों पर काम करती हैं. इस सेशन टाइप में, स्टैंडर्ड OOB specification का इस्तेमाल किया जाता है.

रेंजिंग मॉड्यूल, सिर्फ़ ओओबी डेटा फ़ॉर्मैट और क्रम तय करता है. इसका इस्तेमाल, किसी दूसरे डिवाइस के साथ इंटरैक्ट करने के लिए किया जाता है. यह आस-पास मौजूद डिवाइसों का पता लगाने या कनेक्शन बनाने की सुविधा को मैनेज नहीं करता.

कस्टम ओओबी लागू करना

इस सेशन टाइप (RANGING_SESSION_RAW) में, ऐप्लिकेशन, रेंजिंग मॉड्यूल के ओओबी फ़्लो को बायपास करता है. साथ ही, ओओबी नेगोशिएशन और पैरामीटर को खुद मैनेज करता है. इसका मतलब है कि ऐप्लिकेशन को यह तय करना होगा कि पीयर डिवाइस किन टेक्नोलॉजी के साथ काम करता है. साथ ही, उसे रेंजिंग पैरामीटर पर बातचीत करनी होगी और रेंजिंग सेशन शुरू करना होगा.

रेंजिंग से जुड़ी प्राथमिकताएं

RangingPreference ऑब्जेक्ट का इस्तेमाल करके, रेंज वाले सेशन के लिए चुने गए पैरामीटर की जानकारी दें. इसमें ये शामिल हैं:

  • डिवाइस की भूमिका. इससे पता चलता है कि डिवाइस, कम्यूनिकेशन शुरू करेगा या जवाब देगा.
  • रेंजिंग कॉन्फ़िगरेशन. RangingConfig ऑब्जेक्ट, रेंजिंग सेशन के टाइप और रेंजिंग सेशन शुरू करने के लिए ज़रूरी अन्य पैरामीटर के बारे में बताता है.
  • सेशन का कॉन्फ़िगरेशन. SessionConfig ऑब्जेक्ट, रेंजिंग सेशन पर लागू किए जाने वाले पैरामीटर तय करता है. जैसे, मेज़रमेंट की सीमा, सेंसर फ़्यूज़न, जियोफ़ेंस कॉन्फ़िगरेशन वगैरह.

रेंजिंग की अनुमति

रेंजिंग मॉड्यूल को सभी मौजूदा और आने वाली रेंजिंग टेक्नोलॉजी को ऐक्सेस करने के लिए, नई यूनिफ़ाइड अनुमति (android.permission.RANGING) की ज़रूरत होती है. यह अनुमति NEARBY_DEVICES_PERMISSIONS सूची में शामिल है.

<uses-permission android:name="android.permission.RANGING" />

पाबंदियां और सीमाएं

कई वजहों से, रेंजिंग मॉड्यूल रेंजिंग को सीमित कर सकता है. इनमें ये वजहें शामिल हैं:

  • तीसरे पक्ष के ऐप्लिकेशन को सिर्फ़ ultra-wideband की सुविधा वाले डिवाइसों पर, बैकग्राउंड में रेंजिंग की सुविधा इस्तेमाल करने की अनुमति है. अन्य टेक्नोलॉजी के साथ बैकग्राउंड में रेंजिंग करने की अनुमति नहीं है.
  • डिवाइस पर एक साथ रेंजिंग करने वाले सेशन की तय सीमा पूरी होने पर, रेंजिंग की अनुमति नहीं है.
  • सिस्टम की परफ़ॉर्मेंस से जुड़ी समस्याओं की वजह से, रेंजिंग पर पाबंदी लगाई जा सकती है. जैसे, बैटरी, परफ़ॉर्मेंस या मेमोरी.

रेंजिंग मॉड्यूल की ये सीमाएं हैं:

  • रेंजिंग मॉड्यूल, सिर्फ़ ultra-wideband के लिए, रेंजिंग डेटा को आस-पास मौजूद डिवाइसों पर डिलीवर करने की सुविधा देता है. अन्य टेक्नोलॉजी के लिए, रेंजिंग मॉड्यूल सिर्फ़ रेंजिंग डेटा को शुरू करने वाले डिवाइस पर भेजता है.
  • रेंजिंग मॉड्यूल, सिर्फ़ रॉ रेंजिंग मोड में डिवाइसों को डाइनैमिक तरीके से जोड़ने की सुविधा देता है. यह सुविधा सिर्फ़ अल्ट्रा-वाइडबैंड के लिए उपलब्ध है.
  • रेंजिंग मॉड्यूल, डिफ़ॉल्ट OOB लागू करने के लिए, एक से ज़्यादा अल्ट्रा-वाइडबैंड सेशन के साथ काम नहीं करता. अगर एक से ज़्यादा डिवाइस हैंडल पास किए जाते हैं, तो मॉड्यूल हर उस डिवाइस के लिए वन-टू-वन सेशन बनाता है जिस पर अल्ट्रा-वाइडबैंड की सुविधा काम करती है.

रेंजिंग सेशन करना

रेंजिंग मॉड्यूल का इस्तेमाल करके रेंजिंग सेशन करने के लिए, यह तरीका अपनाएं:

  1. पुष्टि करें कि सभी डिवाइसों पर Android 16 या इसके बाद का वर्शन चल रहा हो.
  2. ऐप्लिकेशन मेनिफ़ेस्ट में, android.permission.RANGING अनुमति का अनुरोध करें.
  3. रेंजिंग टेक्नोलॉजी की क्षमताओं और उपलब्धता का आकलन करें.
  4. रेंजिंग की कार्रवाइयों के लिए, आस-पास मौजूद कोई डिवाइस ढूंढता है.
  5. रेंजिंग सेशन के टाइप में बताए गए किसी भी सेशन टाइप का इस्तेमाल करके, आउट-ऑफ़-बैंड एक्सचेंज के लिए कनेक्शन बनाएं.
  6. रेंजिंग की प्रोसेस शुरू करें और रेंजिंग का डेटा लगातार इकट्ठा करें.
  7. रेंजिंग सेशन बंद करें.

यहां दिए गए कोड के सैंपल में, अनुरोध करने वाले और जवाब देने वाले, दोनों की भूमिकाओं के लिए इन चरणों को दिखाया गया है.

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()
    }
}

Java

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();
    }
}

iOS डिवाइसों के साथ यूडब्ल्यूबी इंटरऑपरेबिलिटी (दूसरे सिस्टम के साथ काम करना)

रेंजिंग मॉड्यूल, iOS डिवाइसों के साथ इंटरऑपरेबिलिटी की सुविधा देता है. इसके लिए, ultra-wideband (UWB) का इस्तेमाल किया जाता है. iOS डिवाइस के साथ रेंज करने के लिए, आपको कस्टम ओओबी इंपलीमेंटेशन का इस्तेमाल करना होगा. साथ ही, रेंजिंग सेशन को उन खास पैरामीटर के साथ कॉन्फ़िगर करना होगा जो Apple Nearby Interaction Accessory Protocol से मेल खाते हों. रेफ़रंस के लिए, सैंपल ऐप्लिकेशन देखें.

RangingPreference बनाते समय, कॉन्फ़िगरेशन के बारे में बताने के लिए RawRangingDevice और UwbRangingParams का इस्तेमाल करें. iOS के साथ काम करने के लिए, ये पैरामीटर ज़रूरी हैं:

  • कॉन्फ़िगरेशन आईडी: UwbRangingParams.CONFIG_UNICAST_DS_TWR का इस्तेमाल करें.
  • सेशन की मुख्य जानकारी: वेंडर आईडी और स्टैटिक STS IV वाला बाइट ऐरे दें.
  • कॉम्प्लेक्स चैनल: चैनल नंबर और प्रीऐंबल इंडेक्स को iOS डिवाइस के कॉन्फ़िगरेशन से मैच करने के लिए सेट करें.

नीचे दिए गए कोड स्निपेट में, iOS रेस्पॉन्डर के साथ रेंज करने वाले इनिशिएटर डिवाइस के लिए RangingPreference बनाने का तरीका बताया गया है:

Kotlin

// Create UwbRangingParams with iOS-specific configuration
val uwbRangingParams = UwbRangingParams.Builder(
    sessionId,
    UwbRangingParams.CONFIG_UNICAST_DS_TWR,
    sourceAddress,
    destinationAddress
)
    .setComplexChannel(
        UwbComplexChannel.Builder()
            .setChannel(channelNumber)
            .setPreambleIndex(preambleIndex)
            .build()
    )
    .setRangingUpdateRate(updateRate)
    .setSessionKeyInfo(sessionKeyInfo) // Vendor ID + STS IV
    .setSlotDuration(slotDuration)
    .build()

// Create RawRangingDevice
val rawRangingDevice = RawRangingDevice.Builder()
    .setRangingDevice(RangingDevice.Builder().build())
    .setUwbRangingParams(uwbRangingParams)
    .build()

// Create SessionConfig
val sessionConfig = SessionConfig.Builder()
    .setAngleOfArrivalNeeded(true)
    .setDataNotificationConfig(DataNotificationConfig.Builder()
        .setNotificationConfigType(DataNotificationConfig.NOTIFICATION_CONFIG_ENABLE)
        .build())
    .build()

// Create RangingPreference for the initiator
val preference = RangingPreference.Builder(
    RangingPreference.DEVICE_ROLE_INITIATOR,
    RawInitiatorRangingConfig.Builder()
        .addRawRangingDevice(rawRangingDevice)
        .build()
)
    .setSessionConfig(sessionConfig)
    .build()

Java

// Create UwbRangingParams with iOS-specific configuration
UwbRangingParams uwbRangingParams = new UwbRangingParams.Builder(
        sessionId,
        UwbRangingParams.CONFIG_UNICAST_DS_TWR,
        sourceAddress,
        destinationAddress)
        .setComplexChannel(new UwbComplexChannel.Builder()
                .setChannel(channelNumber)
                .setPreambleIndex(preambleIndex)
                .build())
        .setRangingUpdateRate(updateRate)
        .setSessionKeyInfo(sessionKeyInfo) // Vendor ID + STS IV
        .setSlotDuration(slotDuration)
        .build();

// Create RawRangingDevice
RawRangingDevice rawRangingDevice = new RawRangingDevice.Builder()
        .setRangingDevice(new RangingDevice.Builder().build())
        .setUwbRangingParams(uwbRangingParams)
        .build();

// Create SessionConfig
SessionConfig sessionConfig = new SessionConfig.Builder()
        .setAngleOfArrivalNeeded(true)
        .setDataNotificationConfig(new DataNotificationConfig.Builder()
                .setNotificationConfigType(DataNotificationConfig.NOTIFICATION_CONFIG_ENABLE)
                .build())
        .build();

// Create RangingPreference for the initiator
RangingPreference preference = new RangingPreference.Builder(
        RangingPreference.DEVICE_ROLE_INITIATOR,
        new RawInitiatorRangingConfig.Builder()
                .addRawRangingDevice(rawRangingDevice)
                .build())
        .setSessionConfig(sessionConfig)
        .build();

UWB Downlink-TDoA API

UWB DL-TDoA API के लिए, Android 17 की नई सुविधाएं देखें.

सैंपल ऐप्लिकेशन

रेंजिंग मॉड्यूल को इस्तेमाल करने के तरीके का पूरा उदाहरण देखने के लिए, AOSP में सैंपल ऐप्लिकेशन देखें. इस सैंपल ऐप्लिकेशन में, दूरी का पता लगाने वाली उन सभी टेक्नोलॉजी को शामिल किया गया है जो Ranging मॉड्यूल के साथ काम करती हैं. साथ ही, इसमें दोनों तरह के सेशन के लिए फ़्लो शामिल हैं.

iOS डिवाइसों के साथ यूडब्ल्यूबी इंटरऑपरेबिलिटी (दूसरे सिस्टम के साथ काम करना)

Android सैंपल ऐप्लिकेशन, iOS सैंपल ऐप्लिकेशन के साथ यूडब्ल्यूबी रेंजिंग सेशन शुरू करने की सुविधा देता है.

दूसरी इमेज. Android और iOS पर UWB का इस्तेमाल.