Intervallo tra i dispositivi

Android 16 introduce il modulo Ranging, che fornisce un'interfaccia unificata e standardizzata per la misurazione precisa della distanza tra i dispositivi. Puoi utilizzare questa API per misurare la distanza e la posizione dei dispositivi peer senza dover gestire singolarmente ogni tecnologia di misurazione della distanza.

Il modulo Ranging supporta le seguenti tecnologie:

Funzionalità e disponibilità dei rilevamenti

La classe RangingManager fornisce alle app informazioni sulle tecnologie di misurazione della distanza supportate dal dispositivo locale, nonché sulla disponibilità e sulle funzionalità di ciascuna tecnologia. Le app possono registrarsi per un Callback per ricevere aggiornamenti su eventuali modifiche alla disponibilità o alle funzionalità di qualsiasi tecnologia supportata.

Ruoli del dispositivo

Un dispositivo che partecipa a una sessione di misurazione della distanza deve essere un iniziatore o un risponditore. Il dispositivo di iniziativa avvia la sessione di misurazione della distanza con uno o più dispositivi di risposta. Un dispositivo di risposta risponde alle richieste di misurazione della distanza da un solo iniziatore alla volta. Puoi specificare il ruolo di un determinato dispositivo in una sessione di misurazione della distanza con la classe RangingPreference.

Tipi di sessioni di misurazione

Quando avvii una sessione di misurazione della distanza tra dispositivi, spesso è necessario stabilire un trasporto di dati out-of-band (OOB) per scambiare i parametri della sessione.

Il modulo Ranging può gestire le negoziazioni OOB per te, ma supporta anche implementazioni OOB personalizzate.

Figura 1. Flusso OOB per i tipi di sessione.

Implementazione OOB predefinita

In questo tipo di sessione (RANGING_SESSION_OOB), il modulo Ranging gestisce le negoziazioni OOB per avviare una sessione di ranging. Seleziona parametri adatti in base alle preferenze di misurazione fornite dall'app e utilizza le tecnologie appropriate in base a ciò che è supportato da entrambi i dispositivi. Questo tipo di sessione utilizza un OOB specification standardizzato.

Il modulo Ranging definisce solo il formato e la sequenza dei dati OOB da utilizzare per interagire con un dispositivo peer. Non gestisce il rilevamento dei dispositivi peer o la creazione di una connessione.

Implementazione OOB personalizzata

In questo tipo di sessione (RANGING_SESSION_RAW), l'app aggira il flusso OOB del modulo di misurazione della distanza e gestisce i propri parametri e la propria negoziazione OOB. Ciò significa che l'app deve determinare le tecnologie supportate dal dispositivo peer, negoziare i parametri di rilevamento e avviare la sessione di rilevamento.

Preferenze di individuazione

Utilizza un oggetto RangingPreference per specificare i parametri preferiti per una sessione di misurazione della distanza. È incluso quanto segue:

  • Ruolo del dispositivo. Indica se il dispositivo sarà l'iniziatore o il rispondente.
  • Configurazione della misurazione. Un oggetto RangingConfig specifica il tipo di sessione di misurazione della distanza e altri parametri necessari per avviarla.
  • Configurazione della sessione. Un oggetto SessionConfig specifica i parametri da applicare alla sessione di misurazione, ad esempio il limite di misurazione, la fusione dei sensori, la configurazione del recinto virtuale e altro ancora.

Autorizzazione di rilevamento della distanza

Il modulo di misurazione della distanza richiede una nuova autorizzazione unificata (android.permission.RANGING) per accedere a tutte le tecnologie di misurazione della distanza attuali e future. Questa autorizzazione è nell'elenco NEARBY_DEVICES_PERMISSIONS.

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

Restrizioni e limitazioni

Il modulo di misurazione della distanza potrebbe limitare la misurazione per diversi motivi, tra cui:

  • Le app di terze parti sono autorizzate a eseguire la misurazione in background con la tecnologia ultra-wideband solo sui dispositivi supportati. La misurazione in background con altre tecnologie non è consentita.
  • La misurazione della distanza non è consentita quando è stato raggiunto il numero massimo di sessioni di misurazione della distanza contemporaneamente per dispositivo.
  • La ricerca potrebbe essere limitata a causa di problemi di integrità del sistema, come batteria, prestazioni o memoria.

Il modulo di misurazione della distanza presenta inoltre le seguenti limitazioni note:

  • Il modulo di misurazione della distanza supporta solo l'invio di dati di misurazione della distanza ai dispositivi peer per la banda ultralarga. Per altre tecnologie, il modulo Ranging invia solo i dati di misurazione al dispositivo di iniziativa.
  • Il modulo di misurazione della distanza supporta l'aggiunta dinamica dei dispositivi solo in modalità di misurazione della distanza non elaborata e solo per la banda ultralarga.
  • Il modulo di misurazione della distanza non supporta le sessioni ultrawideband uno a molti per le implementazioni OOB predefinite. Se passi più handle del dispositivo, il modulo crea una sessione uno a uno per ogni dispositivo peer che supporta la tecnologia ultra-wideband.

Eseguire una sessione di misurazione della distanza

Per eseguire una sessione di misurazione della distanza utilizzando il modulo di misurazione della distanza:

  1. Verifica che tutti i dispositivi funzionino su Android 16 o versioni successive.
  2. Richiedi l'autorizzazione android.permission.RANGING nel file manifest dell'app.
  3. Valuta le funzionalità e la disponibilità delle tecnologie di misurazione della distanza.
  4. Individua un dispositivo peer per le operazioni di misurazione della distanza.
  5. Stabilisci una connessione per uno scambio out-of-band utilizzando uno dei tipi di sessione descritti in Tipi di sessione di misurazione della distanza.
  6. Avvia la misurazione della distanza e acquisisci continuamente i dati di misurazione.
  7. Termina la sessione di misurazione.

Il seguente esempio di codice mostra questi passaggi sia per il ruolo di iniziatore sia per il ruolo di rispondente.

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

App di esempio

Per un esempio end-to-end di come utilizzare il modulo Ranging, consulta l'app di esempio in AOSP. Questa app di esempio copre tutte le tecnologie di misurazione della distanza supportate dal modulo di misurazione della distanza e include i flussi per entrambi i tipi di sessione supportati.