Acessibilidade para aplicações Android

Paula Rosa
Android Dev BR
Published in
11 min readMay 7, 2018

O Android possui um conjunto de recursos/ferramentas que possibilita que pessoas que possuam algum tipo de desabilidade possam executar as mesmas ações que um usuário sem estas desabilidades.

Cada usuário, em algum momento da vida, pode vir a possuir alguma desabilidade, mesmo que seja momentânea.

Um senso realizado no Brasil, datado do ano de 2010 mostra que, pelo menos, 23.9% da população brasileira possui algum tipo de deficiência, sendo que a mais presente é a visual (18.5%) seguido da deficiência motora (7%). (http://www.pessoacomdeficiencia.gov.br/app/sites/default/files/publicacoes/cartilha-censo-2010-pessoas-com-deficienciareduzido.pdf)

O termo acessibilidade tem sido muito utilizado ultimamente, mas não é algo tão novo assim, ela já existia na WEB e se intensificou no mundo mobile. Mas o que é acessibilidade quando falamos de mobile?

Acessibilidade é fornecer uma experiência similar a diversos usuários considerando as possíveis desabilidades que um usuário possua.

Observação: A WEB possui uma cartilha que possui diversas disposições de acessibilidade , criadas pelo W3C (World Wide Web Consortium, é um consórcio internacional que possui organizações filiadas, e uma equipe em tempo integral e o público trabalham juntos para desenvolver padrões para a web)

Em outras palavras, a acessibilidade está muito mais ligada a experiência do usuário (User Experience) do que muitas pessoas imaginam. Ou seja, proporcionar acessibilidade num aplicativo implica em também melhorar a experiência, independente do usuário.

Ao contrário do que algumas pessoas acreditam, para implementar acessibilidade em uma aplicação mobile não é tão complicado assim, algumas poucas linhas de código ou atributos no seu xml de layout e pronto.

Recursos de acessibilidade no Android

Recursos são ferramentas ou funcionalidades do framework de acessibilidade que possuem o intuito de facilitar o uso de uma aplicação ou até mesmo do sistema. Estes recursos ficam disponíveis nas configurações de sistema, e há recursos que já vem instalados no aparelho, e alguns outros recursos podem ser baixados do Google Play. Cada recurso se aplica a uma desabilidade ou um conjunto delas, são eles:

Magnification

É um recurso que permite ampliar o conteúdo da tela do device. Através de um toque triplo, o zoom é aplicado à área permitindo que seja ampliado mais ainda com movimento de arrastar com dois dedos e pinch. Na imagem abaixo é possível ver a ampliação aplicada à tela.

Na imagem, funcionalidade de gesto de ampliação sendo mostrada, com capturas de tela

O zoom só é ativado depois de haver um triplo clique na tela e usar o gesto de segurar (manter o dedo pressionado). O efeito de pinch é aplicado depois que já estiver com zoom na tela.

Para ativar esta funcionalidade: Configurações > Acessibilidade > Gestos de ampliação.

Voice Access

O voice access é um recurso que permite, através de comandos de voz, interagir com o device. Se intensificaram com o surgimento dos wearables, e hoje apresentam uma grande possibilidade para auxiliar nas features que terão suporte a acessibilidade.

Mas no Google IO 2016 foi lançado o VoiceAccess, que permite não somente comandos de voz no app, mas sim comandos voz para atuar no sistema operacional como um todo, permitindo, por exemplo, que você abra um aplicativo e interaja com ele. Este recurso é do tipo built-in, ou seja, as aplicações já está atendendo a ele sem que precise implementar algo, a única sugestão do Google é que o aplicativo esteja seguindo as guidelines.

Ao acionar o recurso, são plotados em cada componente um índice numérico, e o usuário pode tanto acionar ao falar o número quanto ao falar a ação desejada. A imagem abaixo mostra o voice access em funcionamento.

Na imagem mostrando índices numéricos da representação dos componentes quando o voice access está ligado

Um vídeo explicando o funcionamento deste recurso está disponível no youtube: https://www.youtube.com/watch?v=apEz73_H2fU

O Voice Access está em fase beta, e inclusive é possível tornar-se um usuário beta e fazer parte do programa, através do download do app. Para participar do programa, o usuário deve se inscrever no programa beta do voice access: (https://play.google.com/apps/testing/com.google.android.apps.accessibility.voiceaccess)

Switch Access

Também conhecido como troca de acesso, este recurso permite que o usuário navegue pelos elementos da tela e também possa interagir com os elementos que a compõem através de um dispositivo como mostra a figura abaixo:

É basicamente um módulo com 2 botões, sendo um para navegar pelos elementos e outro para selecionar (que seria o equivalente ao toque na tela). Pode estar associado ao talkback, e permite que usuários com desabilidades motoras possam interagir com as aplicações com maior facilidade.

BrailleBack

O brailleback é um recurso bem interessante, pois muitos são os casos de pessoas com desabilidades visuais que não aprenderam o nosso alfabeto, ou seja, que lêem somente em braille, portanto este recurso foi criado pensando nestes casos.

É um teclado que se "monta" conforme o texto desejado. Ele possui furos na parte superior, e na parte inferior possui alguns pinos, que, conforme o conteúdo desejado, estes pinos sobem passando pelos furos, formando textos em braille.

Talkback

O talkback é um dos recursos de acessibilidade mais famosos, e um dos mais utilizados também, permite que pessoas com desabilidades visuais parcial ou total possam interagir com o aparelho somente ouvindo o feedback de audio emitido ao interagir com qualquer componente da tela. A maioria das modificações necessárias podem ser feitas através dos layouts (arquivos .xml), salvo alguns casos que serão abordados neste artigo.

Toda vez que um componente é focado pelo talkback, um som é emitido descrevendo o componente. O componente é falado assim:

Estado + texto componente + tipo de componente
Exemplo: não selecionado + lembrar senha + caixa de seleção

Para interagir com o talkback o usuário utiliza de comandos específicos, como mostra a imagem abaixo:

Na imagem atalhos e gestos para serem usados com takback

O usuário navega por cada tela, basicamente de duas formas: ou explorando a tela através do toque (e escutando cada componente) ou através do movimento de swipe para os lados (que troca o foco para o próximo componente)

Dica: tome cuidado quando desativar o foco de layouts/componentes, fazendo isto você pode prejudicar a acessibilidade, sempre teste o app para ver se a mudança no atributo foco não prejudicou o talkback.

Em termos práticos, o talkback hoje é o recurso que precisa de mais trabalho da equipe de desenvolvimento, e por isso precisamos entender como oferecer acessibilidade quando se utiliza o talkback.

Dar significado aos componentes (nomeação)

O significado dos componentes é um dos itens mais importantes para acessibilidade. Quando não há significado em uma imagem, o talkback pode emitir um áudio similar a um click , que denota para o usuário com desabilidade visual que há algo ali, porém sem descrição. Isto pode prejudicar bastante a experiência, já que este usuário será forçado a "descobrir" o que aquela imagem significa

Alguns botões que ficam sem descrição podem estar com áudio: "botão sem descrição" ou "botão21", portanto, a descrição dos componentes é algo primordial para acessibilidade.

O atributo "android:content_description" , presente em praticamente todos os componentes, é responsável por emitir este áudio. Quando o talkback passar por um componente que tenha este atributo, irá ler o seu conteúdo, fornecendo pro usuário descrição do componente. Veja a imagem abaixo, que usaremos como exemplo:

Na imagem tela de login, com uma imagem representando um alarme, campos de texto representando usuário e senha, e 3 botões para acessar o app através de facebook , twitter ou google plus

Podemos dividir a nomeação de componentes em dois tipos básicos: imagens decorativas e imagens que executam ações.

Imagens decorativas
Para o usuário que utiliza o talkback esta imagem não é importante, pois ela não executa ação. A recomendação no Android é que não coloquemos esta descrição. Para Web já é recomendado descrever mesmo que seja decorativa. O que sugiro é: coloque descrição se realmente for necessário. Neste tipo de imagem colocamos a descrição como "@null" que fará com que o talkback não leia este item.

<ImageView
android:id="@+id/ic_app_notificacao"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_app"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:contentDescription="@null"
/>

A partir da API 16 é possível usar outro atributo android:importantForAccessibility=”no” .

Imagens que executam ações
A imagem que mostra login com redes sociais na verdade não se comporta como uma imagem, já que irá levar o usuário a conectar sua rede social, portanto, ela se comporta como um botão. As imagens que executam ações jamais podem estar sem descrição, pois podem trazer uma experiência confusa para o usuário.

Portanto precisamos descrever o significado da imagem que executa ácão. Fica muito mais fácil de entender, se o desenvolvedor escrever a ação exata, de forma objetiva.

<ImageView
android:id="@+id/botao_facebook"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/facebookicon"
android:contentDescription="@string/logar_com_facebook"
/>

Mas não somente imagens precisam ser nomeadas, mas muitas vezes textos, que devido ao leitor de tela, pode induzir o usuário ao erro, como a imagem abaixo, que mostra um texto que representa parcelas de pagamentos, e outro que representa a data de um vencimento.

Na imagem dois itens: Plano mensal, seguido de um valor de parcelas, e Vencimento, seguido de uma data

Neste caso, o talkback lê as parcelas como: vinte e quatro x de vince e cinco reais e noventa centavos, ou seja, o "x" é lido como uma letra e não como a palavra "vezes". Portanto devemos colocar o atributo texto como "25 x R$ 25,90" e o atributo contentDescription como "25 vezes de R$ 25,90".

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="24 x R$ 25,90"
android:contentDescription="24 vezes de R$ 25,90"
/>

No caso do vencimento, podemos facilitar a leitura, colocando "vencimento em" ao inves somente de "vencimento"

Agrupamento de Views

O agrupamento de views é um item bem interessante, e pode facilitar bastante a leitura do usuário, é muito útil quando temos formulários em que faz mais sentido itens serem lidos em sequência.

Na imagem abaixo, que contém 3 artistas, com 3 musicas, alinhados, ao talkback ler o item Metallica, logo em sequência lê o item Whiskey in the jar, que é o nome da música.

Imagem mostrando agrupamento de views. Na imagem 3 artistas cada um com uma música.

Se os elementos não são agrupados, pode ocorrer uma situação em que o usuário ouça um artista porém a música seja de outro. Ou seja, pode ser que o elemento que ele toque não corresponda ao elemento que deveria ter sido lido pelo talkback.

Para agrupar views, devemos ter um viewGroup como pai destas views, sendo assim, para cada pequeno grupo, deve ter um pai. E adicionamos nesta viewGroup 2 atributos, android:focusable="true" e android:focusableInTouchMode="true".

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:focusable="true"
android:focusableInTouchMode="true"
>

<TextView/>

<TextView/>
</LinearLayout>

Campos de Texto

Os campos de texto possuem um comportamento diferenciado ao serem tocados. Apesar de também possuírem o atributo contentDescription, a recomendação é não utilizá-lo.

Todo EditText, segundo acessibilidade, deve estar acompanhado de um texto acima dele, que irá funcionar como um título do editText em questão, identificando do que aquele campo se trata. Com a chegada do material design, este texto passou a ser o TextInputLayout.

Imagem mostrando componente EditText com TextInputLayout

E então basta colocar no TextInputLayout (ou no texto que deve ficar acima do EditText) o atributo android:labelFor="@+id/editTextId", fazendo isto, já será lido da forma correta.

<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/texto_hint_nome_usuario"
android:labelFor="@+id/texto_nome"

>

<EditText
android:id="@+id/texto_nome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"/>

</android.support.design.widget.TextInputLayout>

Componentes de duplo estado

Muitas aplicações utilizam componentes de duplo estado, um exemplo bem comum de ver em aplicações são os cards que expandem, como na imagem abaixo:

Na imagem mostrando dois estados de um card, um retraído escrito tarefas para lembrar hoje, e outro expandido escrito as tarefas passar no supermercado, lavar a louça e estudar.

O usuário irá mapear a tela no estado inicial, porém o estado posterior precisamos avisar o usuário que um novo estado está sendo mostrado na tela, com o card expandido.

Um outro exemplo onde isto acontece é quando temos uma lista que é mostrada após buscarmos um dado em nuvem, em que no estado inicial mostramos um "loading" e depois carregamos a lista, veja na imagem abaixo:

Duas imagens uma mostrando um estado de carregando (loading) e uma outra imagem mostrando uma lista de jogos com dois botões no topo: buscar e buscar com erro.

Para podermos informar ao talkback que um novo estado surgiu podemos usar algumas técnicas que proporcionarão fazer isto, são elas: live region, accessibility event e announce for accessibility.

Live Region

O live region é usado para situações em que um novo estado surge em tempo de execução.

As views possuem um método para setar o live region, permitindo que ela tenha este comportamento, basta então dentro de View ou ViewCompat chamar este método, passando a view e o modo, como mostra o código:

ViewCompat.setAccessibilityLiveRegion(view,
ViewCompat.ACCESSIBILITY_LIVE_REGION_POLITE)

Há 3 possíveis modos para o live region: polite, assertive e none. O polite irá esperar o talkback terminar o áudio (caso algum esteja em processo) para depois falar o conteúdo, já o assertive irá interromper o áudio do talkback, sua aplicação é bem útil em casos onde há um erro, e logo tem-se que dar este feedback ao usuário, e None irá fazer com que nenhum áudio seja dito.

Accessibility Event

Uma outra forma de fazer com que um áudio seja emitido em tempo de execução é enviar um evento para o talkback. É possível inclusive enviar diversos tipos de evento já existente em componente ao talkback, como cliques, foco, seleção, etc. Neste caso de uma view ficar visível em tempo de execução ele é muito útil, view é quem receberá o foco, no código mostrado abaixo:

view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);

Announce Accessibility

O framework de acessibilidade também permite que um áudio qualquer seja emitido pelo talkback a qualquer momento da aplicação, sendo bem útil para dizer que um componente ficou visível em tempo de execução. Porém ele somente funciona a partir da API 16.

view.announceForAccessibility("qualquer texto");

CustomViews

Os componentes customizados nos permitem criar elementos com comportamentos mais variados, mas para a acessibilidade eles podem apresentar um problema. No quesito acessibilidade, podemos classificá-los em dois tipos: componentes que herdam acessibilidade e componentes que não possuem acessibilidade.

Componentes que herdam acessibilidade são as chamadas Compound Views ou views compostas, são views criadas a partir da junção de elementos dentro de um ViewGroup. Este tipo de CustomView não costuma apresentar problemas com acessibilidade, porém vale a pena conferir se ela atende mesmo.

Compound Views

Componentes que não possuem acessibilidade são aqueles que tiveram alterações nos métodos onDraw e onMeasure, ou que herdam diretamente de View. Geralmente, estes componentes apresentam problemas com acessibilidade, ou seja, a acessibilidade terá que ser feita para estes componentes.

Componentes que herdam de View

No exemplo abaixo, simulei a seguinte situação: quando este meu elemento, uma seta (como da figura acima) fica visível, eu então, dentro da minha customView envio um evento para o framework de acessibilidade, para que meu elemento seja "focado":

arrowView.sendAccessibilityEvent
(AccessibilityEvent.TYPE_VIEW_FOCUSED);

Dentro ainda da customView preciso sobreescrever o método dispatchAndPopulateAccessibilityEvent, como mostra abaixo:

@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
event.getText().add("texto de acessibilidade");
return true;
}

Dicas finais

A acessibilidade não é difícil, e não requer tanto trabalho, já que muita coisa é possível de ser feita via layout. Porém devemos nos ater a alguns pontos:

  • Cuidados com transparência, principalmente aqueles tutoriais, onde uma camada de tela está por cima de outra parte da tela, pois os componentes são lidos por trás da tela
  • Explore vibração, claro sem utilizar em excesso
  • Coloque acessibilidade como parte da concepção e desenvolvimento, pois assim será bem mais fácil de melhorar experiências que não estejam tão boas e detectar possíveis erros para acessibilidade com antecedência, evitando retrabalho nos layouts.
  • Trabalhe em conjunto com o UX e designer da sua empresa, se houver. Vale a pena mostrar pra ela/ele que uma experiência não está tão legal. Peça ajuda.

Não desista. Nem todas as pessoas enxergam o valor da acessibilidade, e por isso é um trabalho de formiguinha convencer as pessoas de que é tão importante quanto qualquer outra coisa, mas tenho certeza que aos poucos as pessoas vão repensando e considerando. Principalmente porque não é algo complexo implementar acessibilidade.

--

--

Paula Rosa
Android Dev BR

Android developer. Android and accessibility Speaker. Software lover :)