Base de l'expérience utilisateur pour le framework haptique

Toutes les améliorations du framework Android liées au haptique sont basées sur un ensemble de principes UX qui évoluent à la même vitesse. Les principes actuels consistent à remplacer les vibrations bourdonnantes par des retours haptiques clairs et à explorer les retours haptiques riches.

Principes de l'expérience utilisateur

Figure 1 : Principes actuels

Le tableau suivant répertorie toutes les API haptiques disponibles :

API Méthodes et constantes Année d'ajout
android.view.HapticFeedbackConstants
  • CONTEXT_CLICK
  • CLOCK_TICK
  • VIRTUAL_KEY
  • KEYBOARD_TAP
  • LONG_PRESS
Avant 2016
  • KEYBOARD_PRESS
  • KEYBOARD_RELEASE
  • TEXT_HANDLE_MOVE
  • VIRTUAL_KEY_RELEASE
2017 (Android 8)
  • CONFIRM
  • REJECT
  • GESTURE_START
  • GESTURE_END
2020 (Android 11)
android.View
  • performHapticFeedback()
Avant 2016
android.os.Vibrator
  • vibrate()
  • hasVibrator()
Avant 2016
  • hasAmplitudeControl()
2017 (Android 8)
  • areAllEffectsSupported()
  • areAllPrimitivesSupported()
  • areEffectsSupported()
  • arePrimitivesSupported()
2020 (Android 11)
android.os.VibrationEffect
  • createOneShot()
  • createWaveform()
2017 (Android 8)
  • EFFECT_TICK
  • EFFECT_CLICK
  • EFFECT_HEAVY_CLICK
  • EFFECT_DOUBLE_CLICK
  • createPredefined()
2019 (Android 10)
android.os.VibrationEffect.Composition
  • PRIMITIVE_TICK
  • PRIMITIVE_CLICK
  • addPrimitive()
  • compose()
2020 (Android 11)
android.media.AudioAttributes.Builder
  • setHapticChannelsMuted()
2019 (Android 10)

Vibration bourdonnante

Depuis les bipeurs et les téléphones multifonctions, les vibrations basées sur un buzzer à masse excentrique rotative (ERM, eccentric rotating mass) de faible qualité, mais peu gourmandes en énergie, sont utilisées pour remplacer la sonnerie en mode silencieux. Les composants matériels anciens qui produisent des bruits audibles forts et désagréables peuvent nuire à l'expérience utilisateur haptique en donnant des impressions de mauvaise qualité (par exemple, un téléphone bon marché et cassé).

Effacer les retours haptiques

Les vibrations claires prennent en charge la sensation de changements d'état discrets (par exemple, les changements binaires lors du processus d'allumage et d'extinction). En raison de la nature de l'affordance discrète, des retours haptiques clairs sont générés en tant qu'entité unique (par exemple, un effet haptique par événement d'entrée).

Android vise à fournir des retours haptiques clairs avec des sensations fortes, mais nettes, plutôt que des sensations floues ou molles.

Les constantes haptiques prédéfinies créées pour prendre en charge les retours haptiques clairs incluent les éléments suivants.

Dans HapticFeedbackConstants :

  • CLOCK_TICK
  • CONFIRM
  • CONTEXT_CLICK
  • GESTURE_END
  • GESTURE_START
  • KEYBOARD_PRESS
  • KEYBOARD_RELEASE
  • KEYBOARD_TAP
  • LONG_PRESS
  • REJECT
  • TEXT_HANDLE_MOVE
  • VIRTUAL_KEY
  • VIRTUAL_KEY_RELEASE

Dans VibrationEffect :

  • EFFECT_CLICK
  • EFFECT_DOUBLE_CLICK
  • EFFECT_HEAVY_CLICK
  • EFFECT_TICK

Il est essentiel de développer des connaissances communes entre les fabricants d'appareils et les développeurs pour améliorer la qualité globale du retour haptique dans l'écosystème Android. Pour en savoir plus sur l'implémentation du retour haptique, consultez la checklist de base, l'évaluation du matériel et le CDD.

Appuyer et relâcher

Figure 2. Appuyer et relâcher

Technologies haptiques avancées

Les retours haptiques riches sont une catégorie de retours haptiques en pleine croissance qui va au-delà des effets basés sur une seule impulsion. Android vise à prendre en charge les retours haptiques riches avec une composabilité et une capacité d'ajustement élevées, avec un niveau de précision élevé. Les cas d'utilisation suivants sont acceptés dans Android 11 ou version antérieure.

Technologies haptiques avancées

Figure 3. Technologie haptique riche avec texture coulissante.

Faire glisser et balayer

Figure 4. Faire glisser et balayer.

Cas d'utilisation 1 : Texture coulissante

Si un effet haptique est répété tandis que le doigt glisse sur une surface tactile (par exemple, lors d'un déplacement, d'un balayage ou de l'exploration de la surface avec une texture haptique fantôme), les effets haptiques répétés sont de préférence nets et subtils.

Si l'effet individuel est bourdonnant plutôt que net, les intervalles entre les répétitions sont probablement effacés. Le résultat est un long bourdonnement, plutôt que plusieurs signaux distincts.

Si l'amplitude n'est pas assez subtile, l'énergie haptique perçue s'accumule au fil de la répétition, ce qui entraîne des sensations haptiques extrêmement fortes à la fin de la répétition.

Implémenter une texture haptique de surface pour les gestes de balayage et de déplacement

Utilisez CLOCK_TICK et TEXT_HANDLE_MOVE dans HapticFeedbackConstants. Ces constantes prédéfinissent les caractéristiques de répétition et d'amplitude.

Créer votre propre effet

Pour créer votre propre effet, composez un design en assemblant des séquences de PRIMITIVE_CLICK et PRIMITIVE_TICK dans VibrationEffect.Composition. Vous pouvez ajuster les caractéristiques de la répétition et de l'échelle d'amplitude à l'aide de addPrimitive(int primitiveID, float scale, int delay). La prise en charge repose sur la fonctionnalité CAP_COMPOSE_EFFECTS de l'interface HAL du vibreur.

Cas d'utilisation 2 : Vibration longue avec effet d'accélération

La vibration longue est une vibration d'amplitude fluide qui passe de 0 à l'amplitude cible. Une longue vibration peut générer des retours haptiques perceptibles pour attirer l'attention. Toutefois, une longue vibration soudaine peut surprendre les utilisateurs dans un environnement calme et produit souvent un bourdonnement audible. Pour générer une longue vibration plus agréable, appliquez l'effet d'accélération au début de la longue vibration. Cela produit une transition d'amplitude fluide qui tend vers l'amplitude cible.

Appliquer l'effet d'accélération

  1. Vérifiez les capacités matérielles du contrôle de l'amplitude avec android.os.Vibrator.hasAmplitudeControl().

    • Le résultat doit être true pour produire un effet d'accélération avec une amplitude variable.
  2. Utilisez VibrationEffect.createWaveform(timings[], amplitudes[], int repeat).

  3. Ajustez les séries timings[] et amplitudes[] pour générer la courbe d'accélération, comme illustré à la figure 5.

Vibration longue

Figure 5. Courbe d'accélération de la vibration longue.

Cas d'utilisation 3 : Haptique couplée à l'audio

Les retours haptiques associés à l'audio sont des schémas haptiques associés au rythme de l'audio pour attirer l'attention de l'utilisateur.

Haptique couplée à l'audio : avantages

Pour implémenter le retour haptique couplé à l'audio, combinez des retours haptiques clairs avec de longues vibrations. Les sensations haptiques claires, fortes mais brèves, offrent des schémas rythmiques distincts. Combinée aux niveaux élevés de stimuli fournis par une longue vibration, cette méthode permet d'attirer l'attention de l'utilisateur.

Il est important de tenir compte des schémas rythmiques de la sensation. S'il n'y a pas de sens du rythme, l'utilisateur perçoit les sensations haptiques comme des vibrations aléatoires et a tendance à les ignorer.

Couplage audio

Figure 6. Exemple de signaux haptiques associés à l'audio.

Rétroaction haptique couplée à l'audio : conseils d'implémentation

Pour implémenter le couplage haptique audio, vous devez avoir des connaissances de base sur la lecture de contenu des canaux audio et haptiques. Gardez à l'esprit les points suivants :

  • Utilisez les classes MediaPlayer ou SoundPool.

    • Les éléments au format OGG avec une clé de métadonnées spéciale (ANDROID_HAPTIC suivi d'un nombre de canaux haptiques) indiquent la présence de données haptiques et la lecture avec MediaPlayer et SoundPool.
  • Indiquez la compatibilité avec le retour haptique et la lecture audio dans audio_policy_configuration.xml.

    • Utilisez un profil de sortie avec un canal haptique AUDIO_CHANNEL_OUT_HAPTIC_A|B.
    • Pour un flux de sortie avec des canaux haptiques, n'oubliez pas que ces canaux sont présentés comme des canaux supplémentaires dans les données.

    Exemple

    Si le masque de canal pour le flux de sortie ressemble à ceci :

    AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A

    Chaque échantillon devrait alors se présenter comme suit :

    AUDIO_LEFT_CHANNEL,AUDIO_RIGHT_CHANNEL,HAPTIC_CHANNEL_A

  • Remplacez AudioAttributes.Builder( ).setHapticChannelsMuted(boolean muted) par false pour lire le canal haptique.

    • Par défaut, les canaux haptiques sont désactivés (true).
    • Les cas d'utilisation incluent les sonneries et les sons d'interface utilisateur avec haptique et rétroaction synchrones.
  • Le HAL du vibreur doit implémenter la prise en charge du contrôle externe.

Haptique couplé à l'audio

Figure 7. Implémenter des retours haptiques couplés à l'audio

Haptique couplée à l'audio : HapticGenerator

HapticGenerator est un effet audio introduit dans Android 12 qui peut générer des données haptiques à partir d'un canal audio et les lire en temps réel en tant que rétroaction haptique couplée à l'audio. L'effet est appliqué à AudioTrack, comme illustré à la figure 8 :

Architecture du générateur haptique

Figure 8. Architecture du générateur haptique.

Cette visualisation de l'architecture montre où le générateur haptique est appliqué au flux audio utilisateur entrant avant d'être envoyé à l'Audio HAL. Le générateur est appliqué après que AudioMixer a divisé les données audio et haptiques, et avant tout autre effet audio. Son résultat remplace toutes les données haptiques précédentes du flux.

Pour vous assurer que l'algorithme de génération haptique génère des haptiques de haute qualité, ajustez l'algorithme de génération au moteur de vibration de l'appareil en modifiant les paramètres qui configurent la chaîne de filtres qu'il applique aux formes d'onde audio. Cette section décrit ces paramètres en détail et explique comment les ajuster à la configuration matérielle.

  • Fréquence de résonance pour le filtre passe-bande

    La fréquence de résonance du vibreur est la fréquence à laquelle un actionneur haptique a une puissance de sortie maximale. Ce paramètre ajuste un anti-résonateur pour aplatir partiellement la fonction de transfert de réponse, afin d'obtenir une bande passante plus large. Le framework Android associe automatiquement cette valeur à la sortie de la méthode Vibrator HAL IVibrator.getResonantFrequency.

    La valeur par défaut de ce paramètre est 150 Hz. Vous pouvez la modifier dans le code.

  • Puissance de normalisation pour l'enveloppe lente

    Ce paramètre détermine l'exposant de la normalisation partielle (contrôle automatique du gain). Sa valeur par défaut est -0.8, ce qui signifie que 80 % de la variation de la plage dynamique est supprimée par cette étape de contrôle du gain. Vous pouvez modifier cette option dans le code.

  • Facteur Q pour le filtre coupe-bande

    Le facteur de qualité du vibreur (facteur Q) est déterminé par deux paramètres :

    • Le Q zéro, le facteur de qualité des zéros dans le filtre coupe-bande qui annule partiellement la résonance

    • Pole Q, le facteur de qualité des pôles dans le filtre coupe-bande

    Le rapport entre ces deux valeurs limite la suppression de la résonance pour amplifier les basses fréquences et élargir la réponse de l'algorithme. Par exemple, les valeurs par défaut de 8 pour le Q de zéro et de 4 pour le Q de pôle produisent un rapport de 2, ce qui limite la suppression de la résonance par un facteur de 2 (6 dB). Le framework Android associe les deux valeurs à la sortie de la méthode HAL Vibrator IVibrator.getQFactor.

    Si les valeurs par défaut ne tiennent pas compte de l'amortissement de la puissance du moteur de votre appareil, nous vous recommandons de modifier les deux valeurs en même temps, en les augmentant ou en les diminuant. Le rapport entre le Q du zéro et le Q du pôle doit être supérieur à 1. Vous pouvez modifier cette option dans le code.

  • Fréquence de coupure pour la distorsion

    La fréquence de coupure est appliquée par un filtre passe-bas qui supprime les vibrations de faible intensité et améliore les vibrations de plus haute intensité à l'aide d'une distorsion cubique. La valeur par défaut est 300 Hz. Vous pouvez la modifier dans le code.

  • Seuil de gain d'entrée et de cube pour la distorsion

    Ces paramètres sont utilisés par un filtre de distorsion non linéaire appliqué à la forme d'onde d'entrée, qui atténue l'amplitude des signaux de basse fréquence et augmente l'amplitude des signaux de haute fréquence.

    • La valeur par défaut du facteur de gain d'entrée est 0,3.
    • La valeur par défaut du seuil de cube est 0,1.

    Nous vous recommandons de modifier les deux valeurs en même temps. Vous les trouverez dans le code.

    Pour en savoir plus sur la fonction appliquée par ce filtre, consultez l'implémentation dans le code.

    Pour en savoir plus sur l'influence de ces deux paramètres sur la sortie, nous vous recommandons de tracer les réponses en fréquence des filtres et d'observer comment elles changent avec différentes valeurs de paramètres.

  • Gain de sortie pour la distorsion

    Ce paramètre contrôle l'amplitude finale de la vibration. Il s'agit d'un gain final appliqué après un limiteur souple qui limite les amplitudes de vibration à moins de 1. Sa valeur par défaut est 1,5, mais vous pouvez la modifier dans le code.

    Si la vibration est trop subtile, augmentez la valeur. Si vous entendez le matériel de l'actionneur cliqueter, diminuez la valeur.