Android

11 mar, 2019

Android: como testar o leitor de tela (talkback) durante o desenvolvimento

Publicidade

Este artigo foi publicado originalmente em: https://www.concrete.com.br/2019/02/06/talkback/.

***

A questão da acessibilidade tem chamado a atenção de grandes empresas (com razão), seja por ser uma parcela do público que antigamente não era vista como consumidora, ou simplesmente pela questão humanitária. De qualquer forma, a iniciativa é louvável.

No campo da tecnologia não é diferente. Cada vez mais temos a necessidade de tornar nossos aplicativos preparados para todas as pessoas, independente de suas necessidades especiais.

Afinal, cerca de 15% da população mundial possui algum tipo de necessidade especial, segundo o The World Bank, e não vamos querer deixar esses usuários de fora das nossas aplicações, certo?

Neste caminho surgiram algumas opções de facilitadores. Um deles é o TalkBack, disponibilizado pela Google, um leitor de tela que oferece feedback por voz   sem a necessidade de estarmos efetivamente olhando para a tela. Ou seja, um cenário que contempla aqueles que possuem necessidades especiais de visão.

Além dos facilitadores, também podemos usar ferramentas de análise para identificar pontos em que é possível melhorar a acessibilidade durante o desenvolvimento das nossas telas e algumas opções de configuração de desenvolvedor resolvem isso rapidinho.

Neste artigo falaremos sobre dois pontos que ajudam a testar o TalkBack durante o desenvolvimento:

  • Speech Output: exibe na UI o texto que será dito pelo leitor de tela
  • Node tree debugging: exibe no logcat as informações da view

O serviço de acessibilidade do sistema operacional usa uma representação separada da UI para operar. Durante a depuração é possível habilitar essas duas opções para exibir o conteúdo daquilo que será dito pelo leitor de telas e visualizar a hierarquia das views e os atributos dos elementos da UI.

Como instalar o TalkBack no emulador

Como o aplicativo – por regra – não é instalado nos emuladores, o primeiro passo é: instalá-lo!

Meu conselho é que, dentre os emuladores que você usa, tenha sempre um com o TalkBack instalado e ativado. Pode ser um diferente daquele que você usa no dia a dia – separe um com essa finalidade, escolhendo até um nome de fácil memorização. Assim, quando precisar validar acessibilidade, já tem um pronto e você ganha tempo.

Depois disso, clone o projeto: https://github.com/google/talkback e atenda aos pré-requisitos (consequentemente o projeto vai estar compilando). Instale o apk do projeto: “./gradlew installDebug”.

Para ativar o TalkBack

  • 1. Abra o Settings.
  • 2. Navegue até Accessibility e selecione Talkback
  • 3. No topo da tela, pressione On/Off para ligar e desligar o TalkBack
  • 4. Para confirmar, selecione o botão OK

Para ativar o Speech Output

Em TalkBack Settings > Developer settings, selecione Display speech output.

Para ativar o Node Tree Debugging

1. Em TalkBack Settings > Developer settings, selecione Enable node tree debugging.

2. Em TalkBack Settings > Developer settings, selecione em “Log output level” o valor Verbose.

3. Configure o gesture do TalkBack para que a node tree seja impressa no logcat.

  • Em TalkBack Settings vá até Gesture
  • Selecione qualquer gesture. Pode ser utilizado qualquer um, até mesmo, por exemplo, o swipe right to up
  • Selecione Print node tree.

Nota: conforme é apontado pela própria Google, a ativação e configuração do TalkBlack pode variar por diferentes motivos, de acordo com a fabricante do aparelho, versão do Android, versão do TalkBack, etc.

Como usar o Speech Output

Após ativar o Speech output, ao selecionar algum item da UI vai aparecer um Toast com a informação que será lida pelo TalkBack. Com isso, é possível validar a acessibilidade de todos os elementos da view.

O uso do Speech output veio de uma necessidade do dia a dia. Eu precisei validar e ajustar a acessibilidade em uma tela complexa, e com o prazo apertado ficar prestando atenção no que era dito pelo leitor de tela acabaria consumindo muito do meu tempo. Usar o Speech output me ajudou bastante, porque o foco passou a ser em ler apenas o que era exibido no Toast.

Como usar o Node Tree Debugging

Após ativar o Node Tree Debugging e configurar o Gesture desejado, é possível ver no logcat as informações sobre a view que recebeu o gesture. É ideal que você use um filtro no logcat, como o valor “TalkBack”, por exemplo.

No exemplo de captura abaixo há informações do botão ‘Hello’ (id=material_button_hello). O logcat não exibe essas informações de forma muito legível, mas é possível (com um pouco de paciência) extrair as informações:

perform action=64=ACTION_ACCESSIBILITY_FOCUS with args=null on node=android.support.v4.view.accessibility.AccessibilityNodeInfoCompat@7477;
boundsInParent: Rect(0, 0–231, 126);
boundsInScreen: Rect(425, 939–656, 1065);
packageName: me.tmonteiro.talkback;
className: android.widget.Button;
text: HELLO;
contentDescription: hello, click here;
viewId: me.tmonteiro.talkback:id/material_button_hello;
checkable: false;
checked: false;
focusable: true;
focused: true;
selected: false;
clickable: true;
longClickable: false;
enabled: true;
password: false;
scrollable: false;
[ACTION_CLEAR_FOCUS, ACTION_SELECT, ACTION_CLEAR_SELECTION, ACTION_CLICK, ACTION_CLEAR_ACCESSIBILITY_FOCUS, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ACTION_SET_SELECTION] for event=type:EVENT_TYPE_ACCESSIBILITY subtype:TYPE_VIEW_HOVER_ENTER time:9382403

Com isso, temos informações da view que são bastante relevantes para análise:

  • Valor do ‘contentDescription’
  • Valor do ‘text’
  • Valor do ‘id’
  • Indicador ‘focused’ marcando se pode ou não receber foco
  • Indicador ‘clickable’ marcando se pode ou não ser ser clicado
  • Ação recebida: [ACTION_ACCESSIBILITY_FOCUS]
  • Ações suportadas: [ACTION_CLEAR_FOCUS, ACTION_CLICK, ACTION_CLEAR_ACCESSIBILITY_FOCUS, etc]

Para as capturas, eu usei o seguinte layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">

    <com.google.android.material.circularreveal.cardview.CircularRevealCardView
            android:layout_margin="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

        <TextView
                android:layout_margin="5dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "/>

    </com.google.android.material.circularreveal.cardview.CircularRevealCardView>

    <CheckBox
            android:id="@+id/checkbox_talkback"
            android:text="Is talback active"
            android:layout_margin="20dp"
            android:layout_gravity="center"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    <RadioGroup
            android:layout_margin="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checkedButton="@+id/first"
            android:orientation="vertical">

        <RadioButton
                android:id="@+id/first"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="first"/>

        <RadioButton
                android:id="@+id/second"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="second"/>

    </RadioGroup>

    <com.google.android.material.button.MaterialButton
            android:id="@+id/material_button_hello"
            android:layout_margin="20dp"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="hello"
            android:contentDescription="hello, click here"
            style="@style/Widget.MaterialComponents.Button.OutlinedButton"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

</LinearLayout>

Quer saber mais? Aqui tem um link com as referências que usei para o artigo. Tem alguma dúvida ou observação? Aproveite os campos abaixo!

Até a próxima!