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 individuellement chaque technologie de mesure de distance.
Le module Ranging est compatible avec les technologies suivantes :
- Bande ultralarge
- Sondage des canaux Bluetooth
- Wi-Fi NAN RTT
- Mesure de la distance par RSSI Bluetooth
Capacités et disponibilités de la mesure de distance
La classe RangingManager fournit aux applications des informations sur les technologies de mesure de 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 informations sur les modifications apportées à la disponibilité ou aux fonctionnalités des technologies compatibles.
Rôles des appareils
Un appareil participant à une session de mesure de distance doit être un initiateur ou un répondeur. L'appareil initiateur démarre la session de mesure de distance avec un ou plusieurs appareils répondeurs. Un appareil répondeur ne répond qu'aux demandes de mesure de distance d'un seul initiateur à la fois. Vous pouvez spécifier le rôle d'un appareil donné dans une session de mesure de distance avec la classe RangingPreference.
Types de sessions de mesure de distance
Lorsque vous démarrez une session de mesure de 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.
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 distance. Il sélectionne les paramètres appropriés en fonction des préférences de mesure de 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 un OOB specification standardisé.
Le module Ranging définit uniquement le format et la séquence des données OOB à utiliser pour interagir avec un appareil pair. Il ne gère pas la découverte 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 distance et démarrer la session de mesure de distance.
Préférences de portée
Utilisez un objet RangingPreference 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 distance. Un objet
RangingConfigspécifie le type de session de mesure de distance et les autres paramètres nécessaires pour démarrer une session de mesure de distance. - Configuration de la session : Un objet
SessionConfigspécifie les paramètres à appliquer à la session de mesure de distance, tels que la limite de mesure, la fusion de capteurs, la configuration de la zone géographique, etc.
Autorisation de mesure de distance
Le module Ranging nécessite une nouvelle autorisation unifiée (android.permission.RANGING) pour accéder à toutes les technologies de mesure de distance actuelles et futures. Cette autorisation figure dans la liste NEARBY_DEVICES_PERMISSIONS.
<uses-permission android:name="android.permission.RANGING" />
Restrictions et limites
Le module Ranging peut restreindre la mesure de distance pour plusieurs raisons, y compris les suivantes :
- Les applications tierces ne sont autorisées à effectuer des mesures de distance en arrière-plan qu'avec la bande ultralarge et uniquement sur les appareils compatibles. La mesure de distance en arrière-plan avec d'autres technologies n'est pas autorisée.
- La mesure de distance n'est pas autorisée lorsque le nombre maximal de sessions de mesure de distance simultanées par appareil a été atteint.
- La mesure de distance peut être limitée en raison de problèmes liés à l'état du système, tels que la batterie, les performances ou la mémoire.
Le module Ranging présente également les limites connues suivantes :
- Le module Ranging ne permet de fournir des données de mesure de distance aux appareils pairs que pour la bande ultralarge. Pour les autres technologies, le module Ranging ne fournit des données de mesure de distance qu'à l'appareil initiateur.
- Le module Ranging n'accepte que l'ajout dynamique d'appareils en mode de mesure de 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 identifiants d'appareil, le module crée une session individuelle pour chaque appareil pair compatible avec la bande ultralarge.
Organiser une session de définition de la gamme
Pour effectuer une session de mesure de distance à l'aide du module Ranging, procédez comme suit :
- Vérifiez que tous les appareils fonctionnent sous Android 16 ou version ultérieure.
- Demandez l'autorisation
android.permission.RANGINGdans le fichier manifeste de l'application. - Évaluez les capacités et la disponibilité des technologies de mesure de distance.
- Découvrez un appareil pair pour les opérations de mesure de distance.
- Établissez une connexion pour un échange hors bande, en utilisant l'un des types de session décrits dans Types de sessions de mesure de distance.
- Lancez la mesure de distance et acquérez en continu les données de mesure de distance.
- Mettez fin à la session de mesure de distance.
L'exemple de code suivant illustre ces étapes pour les rôles d'initiateur et de répondant.
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é UWB avec les appareils iOS
Le module Ranging est compatible avec les appareils iOS utilisant la bande ultralarge (UWB). Pour effectuer une mesure de distance avec un appareil iOS, vous devez utiliser une implémentation OOB personnalisée et configurer la session de mesure de distance avec des paramètres spécifiques correspondant au protocole Apple Nearby Interaction Accessory. Pour obtenir des informations, 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 vecteur d'initialisation STS 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 une plage d'appareils initiateurs 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 Nouvelles fonctionnalités d'Android 17.
Application exemple
Pour obtenir un exemple de bout en bout d'utilisation du module Ranging, consultez l'application exemple dans AOSP. Cette application exemple couvre toutes les technologies de mesure de distance prises en charge par le module Ranging et inclut des flux pour les deux types de sessions compatibles.
Interopérabilité UWB avec les appareils iOS
L'application exemple Android permet de démarrer une session de mesure de distance UWB avec l'application exemple iOS.