محدوده بین دستگاه‌ها

‫Android 16 ماژول «محدوده» را معرفی می‌کند که یک میانای یکپارچه و استانداردشده برای محدوده دقیق بین دستگاه‌ها ارائه می‌دهد. می‌توانید از این سطح میانای برنامه‌سازی کاربردی برای اندازه‌گیری فاصله و موقعیت دستگاه‌های همتا استفاده کنید، بدون اینکه لازم باشد هر فناوری فاصله‌یابی را به‌طور جداگانه مدیریت کنید.

واحد «فاصله‌یابی» از فناوری‌های زیر پشتیبانی می‌کند:

قابلیت‌ها و دردسترس بودن فاصله‌یابی

کلاس RangingManager اطلاعاتی درباره فناوری‌های فاصله‌یابی پشتیبانی‌شده توسط دستگاه محلی و همچنین دردسترس بودن و قابلیت‌های هر فناوری را به برنامه‌ها ارائه می‌دهد. برنامه‌ها می‌توانند برای Callback ثبت‌نام کنند تا به‌روزرسانی‌های مربوط به هرگونه تغییر در دردسترس بودن یا قابلیت‌های هریک از فناوری‌های پشتیبانی‌شده را دریافت کنند.

نقش‌های دستگاه

دستگاهی که در جلسه فاصله‌یابی شرکت می‌کند باید آغازگر یا پاسخ‌دهنده باشد. دستگاه آغازگر جلسه فاصله‌یابی را با یک یا چند دستگاه پاسخ‌دهنده شروع می‌کند. دستگاه پاسخ‌دهنده به درخواست‌های فاصله‌یابی فقط یک آغازگر در هر زمان پاسخ می‌دهد. می‌توانید نقش دستگاه موردنظر را در جلسه فاصله‌یابی با کلاس RangingPreference مشخص کنید.

انواع جلسه فاصله‌یابی

هنگام شروع جلسه فاصله‌یابی بین دستگاه‌ها، اغلب لازم است یک انتقال داده خارج از باند (OOB) برای تبادل پارامترها برای جلسه ایجاد کنید.

واحد «فاصله‌یابی» می‌تواند مذاکرات OOB را برای شما انجام دهد، اما از پیاده‌سازی‌های OOB سفارشی نیز پشتیبانی می‌کند.

شکل ۱. OOB flow for session types.

پیاده‌سازی پیش‌فرض OOB

در این نوع جلسه (RANGING_SESSION_OOB)، واحد «فاصله‌یابی» مذاکرات OOB را برای شروع جلسه فاصله‌یابی مدیریت می‌کند. این API پارامترهای مناسب را براساس اولویت‌های فاصله‌یابی ارائه‌شده توسط برنامه انتخاب می‌کند و از فناوری‌های مناسب براساس آنچه هر دو دستگاه پشتیبانی می‌کنند استفاده می‌کند. این نوع جلسه از OOB specification استانداردشده استفاده می‌کند.

مدول «فاصله‌یابی» فقط قالب و توالی داده‌های OOB را که برای تعامل با دستگاه همتا استفاده می‌شود تعریف می‌کند. این API کاوش دستگاه همتا یا برقراری اتصال را مدیریت نمی‌کند.

پیاده‌سازی سفارشی OOB

در این نوع جلسه (RANGING_SESSION_RAW)، برنامه جریان OOB واحد «فاصله‌یابی» را دور می‌زند و مذاکره و پارامترهای OOB خود را مدیریت می‌کند. یعنی برنامه باید تعیین کند که دستگاه همتا از کدام فناوری‌ها پشتیبانی می‌کند، پارامترهای فاصله‌یابی را مذاکره کند، و جلسه فاصله‌یابی را شروع کند.

اولویت‌های فاصله‌یابی

از شیء RangingPreference برای مشخص کردن پارامترهای انتخاب‌شده برای جلسه فاصله‌یابی استفاده کنید. این موارد شامل موارد زیر است:

  • نقش دستگاه. این نشان می‌دهد که دستگاه آغازگر خواهد بود یا پاسخ‌دهنده.
  • پیکربندی فاصله‌یابی. شیء RangingConfig نوع جلسه فاصله‌یابی و سایر پارامترهای لازم برای شروع جلسه فاصله‌یابی را مشخص می‌کند.
  • پیکربندی جلسه. شیء SessionConfig پارامترهایی را مشخص می‌کند که باید در جلسه فاصله‌یابی اعمال شوند، مانند حد اندازه‌گیری، ادغام حسگر، پیکربندی حصار جغرافیایی، و غیره.

اجازه فاصله‌یابی

ماژول «فاصله‌یابی» برای دسترسی به همه فناوری‌های فاصله‌یابی فعلی و آتی به اجازه یکپارچه جدیدی (android.permission.RANGING) نیاز دارد. این اجازه در فهرست NEARBY_DEVICES_PERMISSIONS قرار دارد.

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

محدودیت‌ها و موانع

مدول «فاصله‌یابی» ممکن است به‌دلایل مختلفی ازجمله موارد زیر فاصله‌یابی را محدود کند:

  • برنامه‌های طرف سوم فقط مجازند بااستفاده از فراپهن‌باند، و فقط در دستگاه‌های پشتیبانی‌شده، محدوده پس‌زمینه را اجرا کنند. محدوده در پس‌زمینه با فناوری‌های دیگر مجاز نیست.
  • وقتی تعداد جلسه‌های هم‌زمان فاصله‌یابی در دستگاه به حداکثر رسیده باشد، فاصله‌یابی مجاز نیست.
  • ممکن است به‌دلیل نگرانی‌های مربوط به سلامت سیستم، مانند باتری، عملکرد، یا حافظه، فاصله‌یابی محدود شود.

واحد «محدوده» همچنین محدودیت‌های شناخته‌شده زیر را دارد:

  • ماژول «فاصله‌یابی» فقط از ارسال داده‌های فاصله‌یابی به دستگاه‌های همتا برای فراپهن‌باند پشتیبانی می‌کند. برای فناوری‌های دیگر، واحد «فاصله‌یابی» فقط داده‌های فاصله‌یابی را به دستگاه آغازگر ارائه می‌دهد.
  • واحد «محدوده» فقط از افزودن پویای دستگاه‌ها در حالت محدوده خام و فقط برای فراپهن‌باند پشتیبانی می‌کند.
  • مدول «محدوده» از جلسه‌های باند فوق‌وسیع یک‌به‌چند برای پیاده‌سازی‌های پیش‌فرض OOB پشتیبانی نمی‌کند. اگر چند دسته دستگاه را ارسال کنید، ماژول برای هر دستگاه همتایی که از فراپهن‌باند پشتیبانی می‌کند، یک جلسه یک‌به‌یک ایجاد می‌کند.

برگزاری جلسه فاصله‌یابی

برای انجام جلسه فاصله‌یابی بااستفاده از ماژول «فاصله‌یابی»، این مراحل را دنبال کنید:

  1. مطمئن شوید همه دستگاه‌ها از Android 16 یا بالاتر استفاده می‌کنند.
  2. در مانیفست برنامه، اجازه android.permission.RANGING را درخواست کنید.
  3. ارزیابی قابلیت‌ها و دردسترس بودن فناوری‌های فاصله‌یابی.
  4. دستگاه همتایی را برای عملیات فاصله‌یابی پیدا کنید.
  5. بااستفاده از یکی از انواع جلسه شرح‌داده‌شده در انواع جلسه فاصله‌یابی، اتصالی برای تبادل خارج‌از باند برقرار کنید.
  6. فاصله‌یابی را شروع کند و به‌طور مداوم داده‌های فاصله‌یابی را دریافت کند.
  7. جلسه فاصله‌یابی را خاتمه دهید.

نمونه کد زیر این مراحل را هم برای نقش آغازگر و هم برای نقش پاسخ‌دهنده نشان می‌دهد.

کاتلین

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

تعامل‌پذیری فراپهن‌باند با دستگاه‌های iOS

مدول «محدوده» از قابلیت همکاری با دستگاه‌های iOS بااستفاده از فراپهن‌باند (UWB) پشتیبانی می‌کند. برای فاصله‌یابی با دستگاه iOS، باید از پیاده‌سازی OOB سفارشی استفاده کنید و جلسه فاصله‌یابی را با پارامترهای خاصی پیکربندی کنید که با پروتکل لوازم جانبی تعامل با اطراف Apple مطابقت داشته باشد. برای مرجع، به برنامه نمونه مراجعه کنید.

هنگام ایجاد RangingPreference، از RawRangingDevice و UwbRangingParams برای مشخص کردن پیکربندی استفاده کنید. پارامترهای زیر برای هم‌کنش‌پذیری iOS بسیار مهم هستند:

  • شناسه پیکربندی: از UwbRangingParams.CONFIG_UNICAST_DS_TWR استفاده کنید.
  • اطلاعات کلید جلسه: آرایه بایتی حاوی شناسه فروشنده و Static STS IV را ارائه دهید.
  • کانال پیچیده: شماره کانال و نمایه مقدمه را طوری تنظیم کنید که با پیکربندی دستگاه iOS مطابقت داشته باشد.

تکه‌کد زیر نحوه ایجاد RangingPreference را برای دستگاه آغازگر درحال فاصله‌یابی با پاسخ‌دهنده iOS نشان می‌دهد:

کاتلین

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

جاوا

// 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 مراجعه کنید. این برنامه نمونه همه فناوری‌های فاصله‌یابی را که توسط مدول «فاصله‌یابی» پشتیبانی می‌شود پوشش می‌دهد و شامل جریان‌هایی برای هر دو نوع جلسه پشتیبانی‌شده است.

تعامل‌پذیری فراپهن‌باند با دستگاه‌های iOS

برنامه نمونه Android از شروع جلسه فاصله‌یابی فراپهن‌باند با برنامه نمونه iOS پشتیبانی می‌کند.

شکل ۲. استفاده از فراپهن‌باند در Android و iOS.