Rentang antar-perangkat

Android 16 memperkenalkan modul Ranging, yang menyediakan antarmuka terpadu dan standar untuk pengukuran jarak yang akurat antar-perangkat. Anda dapat menggunakan platform API ini untuk mengukur jarak dan posisi perangkat peer tanpa perlu menangani setiap teknologi pengukuran jarak secara terpisah.

Modul Pengukuran Jarak mendukung teknologi berikut:

Kemampuan dan ketersediaan rentang

Class RangingManager memberikan informasi kepada aplikasi tentang teknologi pengukuran jarak yang didukung oleh perangkat lokal, serta ketersediaan dan kemampuan setiap teknologi. Aplikasi dapat mendaftar ke Callback untuk menerima update tentang perubahan ketersediaan atau kemampuan teknologi yang didukung.

Peran perangkat

Perangkat yang berpartisipasi dalam sesi pengukuran jarak harus berupa penginisiasi atau pemberi respons. Perangkat pemrakarsa memulai sesi pengukuran jarak dengan satu atau beberapa perangkat responder. Perangkat responder merespons permintaan pengukuran jarak dari hanya satu penginisiasi dalam satu waktu. Anda dapat menentukan peran untuk perangkat tertentu dalam sesi pengukuran jarak dengan class RangingPreference.

Jenis sesi rentang

Saat memulai sesi pengukuran jarak antar-perangkat, sering kali diperlukan untuk menetapkan transportasi data di luar band (OOB) untuk bertukar parameter sesi.

Modul Rentang dapat menangani negosiasi di luar aplikasi untuk Anda, tetapi juga mendukung penerapan di luar aplikasi kustom.

Gambar 1. Alur OOB untuk jenis sesi.

Implementasi OOB default

Dalam jenis sesi ini (RANGING_SESSION_OOB), modul Ranging menangani negosiasi OOB untuk memulai sesi pengukuran jarak. API ini memilih parameter yang sesuai berdasarkan preferensi pengukuran jarak yang diberikan oleh aplikasi, dan menggunakan teknologi yang sesuai berdasarkan dukungan kedua perangkat. Jenis sesi ini menggunakan OOB specification standar.

Modul Ranging hanya menentukan format dan urutan data OOB yang akan digunakan untuk berinteraksi dengan perangkat peer. API ini tidak menangani penemuan perangkat peer atau pembentukan koneksi.

Implementasi OOB kustom

Dalam jenis sesi ini (RANGING_SESSION_RAW), aplikasi melewati alur OOB modul Ranging dan menangani negosiasi dan parameter OOB-nya sendiri. Artinya, aplikasi harus menentukan teknologi yang didukung perangkat peer, menegosiasikan parameter pengukuran jarak, dan memulai sesi pengukuran jarak.

Preferensi rentang

Gunakan objek RangingPreference untuk menentukan parameter yang dipilih untuk sesi rentang. Hal tersebut meliputi:

  • Peran perangkat. Menunjukkan apakah perangkat akan menjadi inisiator atau responden.
  • Konfigurasi pengukuran jarak. Objek RangingConfig menentukan jenis sesi pengukuran jarak dan parameter lain yang diperlukan untuk memulai sesi pengukuran jarak.
  • Konfigurasi sesi. Objek SessionConfig menentukan parameter yang akan diterapkan pada sesi pengukuran jarak seperti batas pengukuran, penggabungan sensor, konfigurasi geofence, dan lainnya.

Izin rentang

Modul Ranging memerlukan izin terpadu baru (android.permission.RANGING) untuk mengakses semua teknologi pengukuran jarak saat ini dan mendatang. Izin ini ada dalam daftar NEARBY_DEVICES_PERMISSIONS.

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

Larangan dan batasan

Modul Ranging dapat membatasi pengukuran jarak karena beberapa alasan, termasuk berikut:

  • Aplikasi pihak ketiga hanya diizinkan untuk melakukan pengukuran jarak di latar belakang dengan ultra-wideband, dan hanya di perangkat yang didukung. Pengukuran jarak di latar belakang dengan teknologi lain tidak diizinkan.
  • Pengukuran jarak tidak diizinkan jika jumlah sesi pengukuran jarak serentak maksimum per perangkat telah tercapai.
  • Pengukuran jarak mungkin dibatasi karena masalah kesehatan sistem seperti baterai, performa, atau memori.

Modul Ranging juga memiliki batasan umum berikut:

  • Modul Ranging hanya mendukung pengiriman data pengukuran jarak ke perangkat peer untuk ultra-wideband. Untuk teknologi lain, modul Ranging hanya mengirimkan data pengukuran jarak ke perangkat inisiator.
  • Modul Pengukuran Jarak hanya mendukung penambahan perangkat secara dinamis dalam mode pengukuran jarak mentah, dan hanya untuk ultra-wideband.
  • Modul Ranging tidak mendukung sesi ultra-wideband one-to-many untuk implementasi OOB default. Jika Anda meneruskan beberapa handle perangkat, modul akan membuat sesi satu-ke-satu untuk setiap perangkat peer yang mendukung ultra-wideband.

Melakukan sesi pengukuran jarak

Untuk melakukan sesi pengukuran jarak menggunakan modul Pengukuran Jarak, ikuti langkah-langkah berikut:

  1. Pastikan semua perangkat beroperasi di Android 16 atau yang lebih baru.
  2. Minta izin android.permission.RANGING di manifes aplikasi.
  3. Menilai kemampuan dan ketersediaan teknologi pengukuran jarak.
  4. Menemukan perangkat peer untuk operasi pengukuran jarak.
  5. Buat koneksi untuk pertukaran out-of-band, menggunakan salah satu jenis sesi yang dijelaskan dalam Jenis sesi pengukuran jarak.
  6. Mulai pengukuran jarak dan terus-menerus mendapatkan data pengukuran jarak.
  7. Menghentikan sesi pengukuran jarak.

Contoh kode berikut menunjukkan langkah-langkah ini untuk peran inisiator dan peran responden.

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

Interoperabilitas UWB dengan perangkat iOS

Modul Ranging mendukung interoperabilitas dengan perangkat iOS menggunakan ultra-wideband (UWB). Untuk melakukan pengukuran jarak dengan perangkat iOS, Anda harus menggunakan implementasi OOB kustom dan mengonfigurasi sesi pengukuran jarak dengan parameter spesifik yang cocok dengan Protokol Aksesori Interaksi Terdekat Apple. Lihat aplikasi contoh untuk referensi.

Saat membuat RangingPreference, gunakan RawRangingDevice dan UwbRangingParams untuk menentukan konfigurasi. Parameter berikut sangat penting untuk interoperabilitas iOS:

  • ID Konfigurasi: Gunakan UwbRangingParams.CONFIG_UNICAST_DS_TWR.
  • Info Kunci Sesi: Berikan array byte yang berisi ID Vendor dan IV STS Statis.
  • Saluran Kompleks: Tetapkan nomor saluran dan indeks preamble agar sesuai dengan konfigurasi perangkat iOS.

Cuplikan kode berikut menunjukkan cara membuat RangingPreference untuk pengukuran jarak perangkat inisiator dengan perangkat responder iOS:

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

Untuk UWB DL-TDoA API, lihat Fitur baru Android 17.

Aplikasi contoh

Untuk contoh end-to-end cara menggunakan modul Ranging, lihat aplikasi contoh di AOSP. Aplikasi contoh ini mencakup semua teknologi pengukuran jarak yang didukung oleh modul Pengukuran Jarak dan mencakup alur untuk kedua jenis sesi yang didukung.

Interoperabilitas UWB dengan perangkat iOS

Aplikasi contoh Android mendukung dimulainya sesi pengukuran jarak UWB dengan aplikasi contoh iOS.

Gambar 2. Penggunaan UWB Android dan iOS.