Bakh’Android


Contexte

À lire

  • Prenez 5mn pour mieux comprendre la question de l’accessibilité numérique si ce n’est pas encore fait (site Bakhtech section Hello’ Accessibilité)
  • Prenez 5mn pour naviguer comme un aveugle avec le lecteur d’écran intégré, Talkback (ou Voice Assistant sur Samsung)
  • Ces 2 premiers points sont essentiels pour comprendre l’accessibilité numérique et constatés par soi même les impacts sur un utilisateur en situation de handicap. La prise en main du lecteur d’écran vous sera aussi utile pour tester et valider vos corrections.

Recommandations

  • Les images porteuses d’information doivent avoir une alternative textuelle pertinente (en utilisant contentDescription)
  • Les images décoratives doivent être ignorées par le lecteur d’écran. C’est le cas par défaut, mais afin d’éviter les warnings lors des tests sur l’absence de contentDescription, vous pouvez l’indiquer via android:contentDescription avec la valeur “@null”.
En savoir plus

Objets et propriétés concernés

Code


			//Donner une alternative textuelle à une image apportant une information
			<ImageView 
				...
				android:contentDescription="@string/desc"
				...
			 />
			 
			 //Indiquer qu'une image est décorative.
			 <ImageView 
				...
				android:contentDescription="@null"
				...
			 />
			

			//Donner une alternative textuelle à une image de manière programmatique (java/kotlin)
			imageView.setContentDescription("Alternative textuelle pertinente")
			

Au delà des normes :

  • Ne jamais donner une information qu’avec la couleur
  • Utiliser des contrastes de couleurs qui respectent les seuils exigés
En savoir plus

Classes et propriétés concernés

  • Classes : View
  • Propriétés : setBackgroundColor, setTextColor

Cas particuliers – Notes techniques – Exceptions à la règle :

  • Non concerné par les critères de contraste de couleur : Logo, dénomination commerciale.
  • Pour corriger les contrastes de couleur une alternative serait d’ajouter un bouton permettant d’inverser les couleurs ou de renforcer les contrastes sur l’ensemble de l’application en un “clic”.

Au delà des normes :

  • Les médias doivent avoir :
    • Une transcription textuelle adjacente ou accessible via un bouton adjacent ou des sous-titres synchronisés pour être accessibles aux personnes ayant un handicap auditif (si nécessaire)
    • Une transcription textuelle ou une audiodescription adjacente accessible via un bouton adjacent pour être accessibles aux personnes ayant un handicap visuel (si nécessaire)
  • Chaque son de plus de 3 secondes déclenché automatiquement doit être contrôlable par l’utilisateur (bouton stop, mute ou volume spécifique)
  • Les boutons de controles des medias doivent être compatible avec les technologies d’assistances

Cas particuliers – Notes techniques – Exceptions à la règle :

  • Le média est utilisé comme CAPTCHA ou test
  • Le média est décoratif (dans ce cas, vérifier qu’il soit bien ignoré par le lecteur d’écran)

  • Les composants customs doivent être totalement contrôlables (utilisables) par le clavier et tout dispositif de pointage. Les informations suivantes en particulier : nom, role, valeur, paramétrage et changements d’état du composant doivent être restitués au lecteur d’écran. À défaut une alternative pertinente et fonctionnelle avec ces outils doit être proposée.
  • Les messages de statut doivent être correctement restitués au lecteur d’écran

Classes et propriétés concernés

  • Classes : View
  • Propriétés : contentDescription, announceForAccessibility, accessibilityLiveRegion

Code


		//Nom, role  et état du composant (exemple avec un onglet custom)
		tabView.setContentDescription = "Onglet 1 sur 2, selectionné"
		
		//Faire lire un texte au lecteur d'écran
		view.announceForAccessibility("Texte à lire") //(La vue doit être visible au moment ou announceForAccessibility est appelé)
		
		//Déclencher une vocalisation en cas de changement de contenu dans une vue
		view.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE) //attend la fin des annonces en court d'abord
		view.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE) //interrompt les annonces en court et notifie l'utilisateur
		
		//Permettre à un element custom de recevoir le focus
		view.setFocusable(View.FOCUSABLE)
		
		//Exemple de selecteur pour rendre visible le focus sur un élément
		<selector xmlns:android="http://schemas.android.com/apk/res/android">
			<item android:state_focused="true" android:state_pressed="false">
				<shape>
						<solid android:color="#00ff00" />
				</shape>
			</item>
		</selector>
		
	

Cas particuliers – Notes techniques – Exceptions à la règle :

  • Il existe une gestion de cas particulier lorsque la fonctionnalité dépend de l’utilisation d’un gestionnaire d’événement sans équivalent universel ; par exemple, une application de dessin à main levée ne pourra pas être rendue contrôlable via les technologies d’assistances. Dans ces situations, le critère est non applicable.

  • Chaque écran doit avoir un titre qui lui est propre ou qui permet de se repérer dans la navigation
  • Indiquer au lecteur d’écran les changements de langue dans une vue

Html, CSS et JS concernés

  • Classes : TextView, LocaleSpan

Code


				//Indiquer que le texte d'un textview est en anglais (kotlin
				var string = "This is an english text"
            	var spannableString = SpannableString(string)
            	var localeSpan = LocaleSpan(Locale.ENGLISH)
            	spannableString.setSpan(localeSpan,0,string.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            	textView.text = spannableString
			

  • Utiliser accessibilityHeading pour indiquer qu’un texte est un titre
  • Indiquer la présence de citation
En savoir plus
  • Classes : TextView
  • Propriétés :accessibilityHeading, contentDescription

Code


				//Indiquer qu'un texte est un titre (xml)
				<TextView
                    android:accessibilityHeading="true"
                    android:text="@string/titre"
            	/>
				
			

				//Indiquer qu'un texte est un titre (java)
				textView.setAccessibilityHeading(true)
				
				//Indiquer qu'un texte est un titre (kotlin)
				textView.isAccessibilityHeading = true
				
				//Indiquer qu'un texte est une citation (java)
				textView.setContentDescription("Citation : " + textView.getText())
				
				//Indiquer qu'un texte est une citation (kotlin)
				textView.contentDescription = "Citation : " + textView.text
			

  • Utiliser des unités de taille dynamiques (exemple : sp) afin que l’utilisateur puisse ajuster la taille des textes via les paramètres d’accessibilité
  • Le texte doit avoir une taille minimum de 14sp
  • Le contenu visible doit le rester quelque soit la taille de texte choisi par l’utilisateur
  • Chaque lien dont la nature n’est pas évidente doit être visible par rapport à son environnement
  • Les contenus cachés doivent aussi être ignorés par les technologies d’assistance
  • Ne donner aucune information uniquement avec la forme, la taille ou la position
  • Le contenu doit être présenté sans avoir besoin d’un scrolling vertical si le sens de lecture est horizontal d’un scrolling horizontal si le sens de lecture est vertical

Classes et propriétés concernés

  • Classes : View, TextView, EditText

Code


					//Masquer un élément au lecteur d'écran (xml)
					<View
						...
						android:importantForAccessibility="no"
						...
					>
					
				

					//Masquer un élément au lecteur d'écran (java/kotlin)
					view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO)
		
					
					
				

Cas particuliers – Notes techniques – Exceptions à la règle :

  • Dans le cas des textes en image et des sous-titres de vidéo le critère sur la lisibilité du contenu après zoom du texte n’est pas applicable
  • Le critère sur l’absence scrolling n’est pas applicables sur les images, graphiques, vidéos, jeux, présentations, tableaux de données, interface où il est nécessaire d’avoir un ascenseur horizontal lors de la manipulation de l’interface et navigateurs mobiles

  • Chaque champ du formulaire doit être associé à une étiquette pertinente, les 2 doivent être accolés (étiquette au dessus ou à gauche du champ). A défaut, fournir un attribut hint indiquant les données à entrer.
  • Indiquer la présence de champ obligatoire ainsi que le type de données attendu si nécéssaire
  • Utiliser le type de clavier correspondant au type de données à entrer pour faciliter la saisie
  • Dans les cas suivants proposer à l’utilisateur de confirmer son action : modification ou suppression de données, réponse à un test ou à un examen, validation aux conséquences financières ou juridiques

Classes et Propriétés concernés

  • Classes: TextView, EditText, TextInputLayout
  • Propriétés : labelFor, hint, inputType

Code


			
				//Exemple champ de formulaire accessible avec  labelfor (xml)
				<TextInputView
        
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
					android:text="@string/email"
					android:labelFor="@id/etEmail"
            	/>
                <EditText
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:inputType="textEmailAddress"
                        android:id="@+id/etEmail"
                />
            
				
				//Exemple champ de formulaire accessible avec hint (xml)
				<TextInputLayout
                    android:id="@+id/text_email_layout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
            	>
                <EditText
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:inputType="textEmailAddress"
                        android:id="@+id/etEmail"
                        android:hint="@string/email"
                />
            	</TextInputLayout>
				
				
			

  • L’ordre de parcours avec avec le lecteur d’écran doit être cohérent
  • Idem avec un clavier
  • S’il est plus cohérent qu’un ensemble d’éléments soient lu en une seule fois par le lecteur d’écran, il est possible des les regrouper dans un conteneur avec android:focusable=”true” (ou android:screenReaderFocusable sur Android 9 et plus)

Classes et propriétés concernés

Code


				//Indiquer qu'une vue doit être lu par le lecteur d'écran avant celle spécifié en paramètre (xml)
				<View
						...
						android:accessibilityTraversalBefore="@id/view2"
						...
				>
				
				
				//Indiquer qu'une vue doit être lu par le lecteur d'écran après celle spécifié en paramètre (xml)
				<View
						...
						android:accessibilityTraversalAfter="@id/view2"
						...
				>
			

				//Indiquer qu'une vue doit être lu par le lecteur d'écran avant celle spécifié en paramètre (kotlin/java)
				view.setAccessibilityTraversalBefore(viewID)
				
				
				//Indiquer qu'une vue doit être lu par le lecteur d'écran après celle spécifié en paramètre (kotlin/java)
				view.setAccessibilityTraversalAfter(viewID)
				
				//Changer l'ordre de focus si celui par défaut n'est pas cohérent
				view.setNextFocusDownId(viewID)
				view.setNextFocusLeftId(viewID)
				view.setNextFocusRightId(viewID)
				view.setNextFocusUpId(viewID)
			

Au delà des normes :

  • Ne changer l’ordre de parcours au lecteur d’écran clavier que si celui par défaut n’est pas cohérent
  • Il est préférable de changer l’ordre de parcours de manière programatique afin de s’assurer que toutes les vues ont été crées.

  • L’utilisateur doit avoir le contrôle de chaque limite de temps qui modifie le contenu
  • L’ouverture d’une nouvelle fenêtre ne doit pas être déclenché sans action de l’utilisateur
  • Les documents bureautiques en téléchargement doivent aussi être accessibles tout en apportant la même information
  • Prévoir une alternative pertinente pour les contenus cryptiques (art ASCII, émoticon, syntaxe cryptique)
  • Utiliser correctement les changements brusques de luminosité ou les effets flash
  • Chaque contenu en mouvement ou clignotant doit être contrôlable par l’utilisateur
  • Le contenu doit être consultable quelque soit l’orientation de l’écran
  • Les fonctionnalités utilisables ou disponibles au moyen d’un geste complexe doivent aussi être disponibles à l’aide d’un geste simple
  • les actions déclenchées au moyen d’un dispositif de pointage sur un point unique de l’écran peuvent-elles faire l’objet d’une annulation
  • les fonctionnalités qui impliquent un mouvement de l’appareil ou vers l’appareil doivent pouvoir être satisfaites de manière alternative

Cas particuliers – Notes techniques – Exceptions à la règle :

  • Le critère sur la limite de temps n’est pas applicable lorsque celle ci est essentielle, notamment lorsqu’elle ne pourrait pas être supprimée sans changer fondamentalement le contenu ou les fonctionnalités liées au contenu
  • Le critère sur l’orientation de l’écran n’est pas applicable si celle ci est essentielle à l’utilisation de l’interface. (ex : jeu)
  • Idem pour le critère sur les mouvements de l’appareil. (ex : podomètre)
  • Le critère sur les gestes complexes ne s’appliquent pas aux gestes requis par l’agent utilisateur ou le système d’exploitation
  • Idem pour le critère sur les actions déclenchées au moyen d’un dispositif de pointage. De plus les fonctionnalités qui imitent un clavier ne sont pas concernés

  • Pour que les webView soient accessibles, il faut que le contenu HTML qu’elles contiennent le soit, et utiliser setJavaScriptEnabled pour autoriser le javascript dans la WebView

Classes et propriétés concernés

Code


				//Autoriser le js dans une webview(java)
				webView.getSettings().setJavaScriptEnabled(true)
				
				
				//Autoriser le js dans une webview (kotlin)
				webView.settings.javaScriptEnabled = true