Plage de portée entre les appareils

Android 16 introduit le module Ranging, qui fournit une interface unifiée et standardisée pour une mesure précise de la distance entre les appareils. Vous pouvez utiliser cette surface d'API pour mesurer la distance et la position des appareils pairs sans avoir à gérer chaque technologie de mesure individuellement.

Le module Ranging est compatible avec les technologies suivantes :

Capacités et disponibilités de la mesure de la distance

La classe RangingManager fournit aux applications des informations sur les technologies de mesure de la distance compatibles avec l'appareil local, ainsi que sur la disponibilité et les capacités de chaque technologie. Les applications peuvent s'inscrire à un Callback pour recevoir des mises à jour sur les modifications apportées à la disponibilité ou aux capacités des technologies compatibles.

Rôles des appareils

Un appareil participant à une session de mesure de la distance doit être un initiateur ou un répondeur. L'appareil initiateur démarre la session de mesure de la distance avec un ou plusieurs appareils répondeurs. Un appareil répondeur ne répond qu'aux requêtes de mesure de la distance d'un seul initiateur à la fois. Vous pouvez spécifier le rôle d'un appareil donné dans une session de mesure de la distance avec la RangingPreference classe.

Types de sessions de mesure de la distance

Lorsque vous démarrez une session de mesure de la distance entre des appareils, il est souvent nécessaire d'établir un transport de données hors bande (OOB) pour échanger les paramètres de la session.

Le module Ranging peut gérer les négociations OOB pour vous, mais il est également compatible avec les implémentations OOB personnalisées.

Figure 1. Flux OOB pour les types de sessions.

Implémentation OOB par défaut

Dans ce type de session (RANGING_SESSION_OOB), le module Ranging gère les négociations OOB pour démarrer une session de mesure de la distance. Il sélectionne les paramètres appropriés en fonction des préférences de mesure de la distance fournies par l'application et utilise les technologies appropriées en fonction de ce que les deux appareils prennent en charge. Ce type de session utilise une OOB specificationstandardisée.

Le module Ranging ne définit que le format de données et la séquence OOB à utiliser pour interagir avec un appareil pair. Il ne gère pas la détection des appareils pairs ni l'établissement de la connexion.

Implémentation OOB personnalisée

Dans ce type de session (RANGING_SESSION_RAW), l'application contourne le flux OOB du module Ranging et gère sa propre négociation et ses propres paramètres OOB. Cela signifie que l'application doit déterminer les technologies compatibles avec l'appareil pair, négocier les paramètres de mesure de la distance et démarrer la session de mesure de la distance.

Préférences de mesure de la distance

Utilisez un RangingPreference objet pour spécifier les paramètres sélectionnés pour une session de mesure de la distance. et vous devriez pouvoir :

  • Rôle de l'appareil. Indique si l'appareil sera l'initiateur ou le répondeur.
  • Configuration de la mesure de la distance. Un objet RangingConfig spécifie le type de session de mesure de la distance et les autres paramètres nécessaires pour démarrer une session de mesure de la distance.
  • Configuration de la session. Un objet SessionConfig spécifie les paramètres à appliquer à la session de mesure de la distance, tels que la limite de mesure, la fusion de capteurs, la configuration de la zone géographique, etc.

Autorisation de mesure de la distance

Le module Ranging nécessite une nouvelle autorisation unifiée (android.permission.RANGING) pour accéder à toutes les technologies de mesure de la distance actuelles et futures. Cette autorisation figure dans la liste NEARBY_DEVICES_PERMISSIONS.

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

Restrictions et limitations

Le module Ranging peut restreindre la mesure de la distance pour plusieurs raisons, y compris les suivantes :

  • Les applications tierces ne sont autorisées à effectuer une mesure de la distance en arrière-plan qu'avec la bande ultralarge et uniquement sur les appareils compatibles. La mesure de la distance en arrière-plan avec d'autres technologies n'est pas autorisée.
  • La mesure de la distance n'est pas autorisée lorsque le nombre maximal de sessions de mesure de la distance simultanées par appareil a été atteint.
  • La mesure de la distance peut être limitée en raison de problèmes d'état du système tels que la batterie, les performances ou la mémoire.

Le module Ranging présente également les limitations connues suivantes :

  • Le module Ranging n'est compatible qu'avec la diffusion de données de mesure de la distance aux appareils pairs pour la bande ultralarge. Pour les autres technologies, le module Ranging ne diffuse les données de mesure de la distance qu'à l'appareil initiateur.
  • Le module Ranging n'est compatible qu'avec l'ajout dynamique d'appareils en mode de mesure de la distance brute, et uniquement pour la bande ultralarge.
  • Le module Ranging n'est pas compatible avec les sessions de bande ultralarge de type "un-à-plusieurs" pour les implémentations OOB par défaut. Si vous transmettez plusieurs handles d'appareils, le module crée une session individuelle pour chaque appareil pair compatible avec la bande ultralarge.

Effectuer une session de mesure de la distance

Pour effectuer une session de mesure de la distance à l'aide du module Ranging, procédez comme suit :

  1. Vérifiez que tous les appareils fonctionnent sous Android 16 ou version ultérieure.
  2. Demandez l'android.permission.RANGING autorisation dans le fichier manifeste de l'application.
  3. Évaluez les capacités et la disponibilité des technologies de mesure de la distance.
  4. Découvrez un appareil pair pour les opérations de mesure de la distance.
  5. Établissez une connexion pour un échange hors bande, à l'aide de l'un des types de sessions décrits dans Types de sessions de mesure de la distance.
  6. Lancez la mesure de la distance et acquérez en continu les données de mesure de la distance.
  7. Mettez fin à la session de mesure de la distance.

L'exemple de code suivant illustre ces étapes pour le rôle d'initiateur et le rôle de répondeur.

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

Interopérabilité de la bande ultralarge avec les appareils iOS

Le module Ranging est compatible avec l'interopérabilité avec les appareils iOS à l'aide de la bande ultralarge (UWB). Pour mesurer la distance avec un appareil iOS, vous devez utiliser une implémentation OOB personnalisée et configurer la session de mesure de la distance avec des paramètres spécifiques correspondant au protocole d'accessoire d'interaction à proximité d'Apple. Pour référence, consultez l'exemple d'application.

Lorsque vous créez le RangingPreference, utilisez RawRangingDevice et UwbRangingParams pour spécifier la configuration. Les paramètres suivants sont essentiels pour l'interopérabilité avec iOS :

  • ID de configuration : utilisez UwbRangingParams.CONFIG_UNICAST_DS_TWR.
  • Informations sur la clé de session : fournissez un tableau d'octets contenant l'ID du fournisseur et le STS IV statique.
  • Canal complexe : définissez le numéro de canal et l'index de préambule pour qu'ils correspondent à la configuration de l'appareil iOS.

L'extrait de code suivant montre comment créer un RangingPreference pour un appareil initiateur mesurant la distance avec un répondeur 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();

API UWB Downlink-TDoA

Pour l'API UWB DL-TDoA, consultez les nouvelles fonctionnalités d'Android 17.

Application exemple

Pour obtenir un exemple de bout en bout d'utilisation du module Ranging, consultez l'exemple d'application dans AOSP. Cet exemple d'application couvre toutes les technologies de mesure de la distance compatibles avec le module Ranging et inclut des flux pour les deux types de sessions compatibles.

Interopérabilité de la bande ultralarge avec les appareils iOS

L'application exemple Android permet de démarrer une session de mesure de la distance UWB avec l'application exemple iOS.

Figure 2. Utilisation de la bande ultralarge sur Android et iOS.