Zasięg między urządzeniami

Android 16 wprowadza moduł pomiaru odległości, który zapewnia ujednolicony i ustandaryzowany interfejs do dokładnego pomiaru odległości między urządzeniami. Za pomocą tej interfejsu API możesz mierzyć odległość i położenie urządzeń bez konieczności obsługi każdej technologii pomiaru odległości osobno.

Moduł określania pozycji obsługuje te technologie:

Możliwości i dostępność pomiarów zasięgu

Klasa RangingManager udostępnia aplikacjom informacje o technologiach pomiaru odległości obsługiwanych przez lokalne urządzenie, a także o dostępności i możliwościach każdej z nich. Aplikacje mogą rejestrować się w Callback, aby otrzymywać informacje o zmianach w dostępności lub możliwościach obsługiwanych technologii.

Role urządzenia

Urządzenie biorące udział w sesji pomiaru zasięgu musi być albo inicjatorem, albo odpowiadającym. Urządzenie inicjujące rozpoczyna sesję pomiaru zasięgu z jednym lub wieloma urządzeniami odpowiadającymi. Urządzenie odpowiadające na żądanie określania odległości odpowiada na żądania tylko jednego inicjatora naraz. Podczas sesji pomiarowej możesz określić rolę danego urządzenia za pomocą klasy RangingPreference.

Typy sesji ustalania pozycji

Podczas uruchamiania sesji pomiaru zasięgu między urządzeniami często konieczne jest ustanowienie transportu danych poza pasmem (OOB) w celu wymiany parametrów sesji.

Moduł Rangowanie może prowadzić negocjacje poza ekranem w Twoim imieniu, ale obsługuje też niestandardowe implementacje poza ekranem.

Rysunek 1. Proces OOB dla typów sesji.

Domyślna implementacja OOB

W przypadku tego typu sesji (RANGING_SESSION_OOB) moduł Ranging obsługuje negocjacje OOB, aby rozpocząć sesję pomiaru zasięgu. Wybiera odpowiednie parametry na podstawie preferencji podanych przez aplikację i korzysta z odpowiednich technologii na podstawie tego, co obsługują oba urządzenia. Ten typ sesji korzysta ze standaryzowanego OOB specification.

Moduł określa tylko format i sekwencję danych OOB, które mają być używane do interakcji z urządzeniem peer. Nie obsługuje wykrywania urządzeń i nawiązywania połączeń.

Niestandardowa implementacja powiadomień o wypadkach

W tym typie sesji (RANGING_SESSION_RAW) aplikacja pomija proces OOB w module Rangowanie i samodzielnie obsługuje negocjacje i parametry OOB. Oznacza to, że aplikacja musi określić, które technologie obsługuje urządzenie peer, wynegocjować parametry pomiaru zasięgu i rozpocząć sesję pomiaru zasięgu.

Ustawienia rankingu

Aby określić parametry sesji pomiarowej, użyj obiektu RangingPreference. między innymi na następujące działania:

  • Rola urządzenia. Wskazuje, czy urządzenie będzie inicjatorem, czy responderem.
  • Konfiguracja pomiaru zasięgu. Obiekt RangingConfig określa typ sesji pomiaru zasięgu oraz inne parametry potrzebne do rozpoczęcia sesji pomiaru zasięgu.
  • Konfiguracja sesji Obiekt SessionConfig określa parametry, które mają być stosowane w sesji pomiaru, takie jak limit pomiaru, fuzja czujników, konfiguracja geoogrodzenia itp.

Uprawnienia dotyczące pomiaru zasięgu

Moduł określania zasięgu wymaga nowego, ujednoliconego uprawnienia (android.permission.RANGING) umożliwiającego dostęp do wszystkich obecnych i przyszłych technologii określania zasięgu. To uprawnienie znajduje się na liście NEARBY_DEVICES_PERMISSIONS.

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

Ograniczenia

Moduł określania zasięgu może ograniczać określanie zasięgu z kilku powodów, m.in.:

  • Aplikacje innych firm mogą wykonywać pomiary w tle w zakresie ultraszerokokresowym tylko na obsługiwanych urządzeniach. Wykrywanie zasięgu w tle przy użyciu innych technologii jest niedozwolone.
  • Określanie zasięgu nie jest dozwolone, gdy osiągnięto maksymalną liczbę równoczesnych sesji określania zasięgu na urządzeniu.
  • Ranking może być ograniczony z powodu problemów z działaniem systemu, takich jak bateria, wydajność lub pamięć.

Moduł określania pozycji ma też te znane ograniczenia:

  • Moduł pomiaru zasięgu obsługuje tylko przesyłanie danych pomiaru zasięgu do urządzeń peer w przypadku łącza ultraszerokopasmowego. W przypadku innych technologii moduł pomiaru odległości przesyła dane pomiarowe tylko do urządzenia inicjującego.
  • Moduł pomiarów zasięgu obsługuje dynamiczne dodawanie urządzeń tylko w nieprzetworzonym trybie pomiarów zasięgu i tylko w przypadku ultraszerokokresowych sieci bezprzewodowych.
  • Moduł określania zasięgu nie obsługuje sesji ultraszerokokreskowych jeden-do-wielu w przypadku domyślnych implementacji OOB. Jeśli przekażesz wiele identyfikatorów urządzeń, moduł utworzy sesję jeden-do-jednego dla każdego urządzenia peer, które obsługuje ultraszerokokalisty zakres.

Przeprowadzanie sesji pomiarowej

Aby przeprowadzić sesję pomiaru zasięgu za pomocą modułu pomiaru zasięgu:

  1. Sprawdź, czy wszystkie urządzenia działają na Androidzie 16 lub nowszym.
  2. W pliku manifestu aplikacji poproś o uprawnienia android.permission.RANGING.
  3. Ocenianie możliwości i dostępności technologii pomiarowych.
  4. wykryć urządzenie peer do operacji pomiarowych;
  5. Nawiązywanie połączenia w celu wymiany danych poza pasmem za pomocą jednego z typów sesji opisanych w artykule Typy sesji pomiarów zasięgu.
  6. Inicjowanie pomiarów i ciągłe uzyskiwanie danych pomiarowych.
  7. Zakończ sesję pomiarową.

Poniższy przykładowy kod pokazuje te kroki zarówno dla inicjatora, jak i odpowiedzi.

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

Przykładowa aplikacja

Przykładowe użycie modułu ustalania kolejności znajdziesz w próbnej aplikacji w AOSP. Ta przykładowa aplikacja obejmuje wszystkie technologie określania zasięgu obsługiwane przez moduł Ranging i zawiera przepływy dla obu obsługiwanych typów sesji.