Einen eigenen Bedienungshilfe-Dienst erstellen (Views)

Konzepte und Jetpack Compose-Implementierung

Eine Bedienungshilfe ist eine App, die die Benutzeroberfläche verbessert, um Nutzern mit Behinderungen oder Nutzern, die vorübergehend nicht in der Lage sind, vollständig mit einem Gerät zu interagieren, zu helfen. Nutzer, die beispielsweise Auto fahren, sich um ein kleines Kind kümmern oder auf einer sehr lauten Party sind, benötigen möglicherweise zusätzliches oder alternatives Feedback über die Benutzeroberfläche.

Android bietet Standard-Bedienungshilfen wie TalkBack. Entwickler können eigene Dienste erstellen und verteilen. In diesem Dokument werden die Grundlagen für die Entwicklung einer Bedienungshilfe erläutert.

Ein Bedienungshilfe kann mit einer normalen App gebündelt oder als eigenständiges Android-Projekt erstellt werden. Die Schritte zum Erstellen des Dienstes sind in beiden Fällen gleich.

Bedienungshilfe erstellen

Erstellen Sie in Ihrem Projekt eine Klasse, die AccessibilityService erweitert:

Kotlin

package com.example.android.apis.accessibility

import android.accessibilityservice.AccessibilityService
import android.view.accessibility.AccessibilityEvent

class MyAccessibilityService : AccessibilityService() {
...
    override fun onInterrupt() {}

    override fun onAccessibilityEvent(event: AccessibilityEvent?) {}
...
}

Java

package com.example.android.apis.accessibility;

import android.accessibilityservice.AccessibilityService;
import android.view.accessibility.AccessibilityEvent;

public class MyAccessibilityService extends AccessibilityService {
...
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
    }

    @Override
    public void onInterrupt() {
    }

...
}

Wenn Sie für diese Service ein neues Projekt erstellen und keine App damit verknüpfen möchten, können Sie die Starter-Klasse Activity aus Ihrem Quellcode entfernen.

Manifestdeklarationen und Berechtigungen

Apps, die Bedienungshilfen bereitstellen, müssen bestimmte Deklarationen in ihren App-Manifesten enthalten, damit sie vom Android-System als Bedienungshilfe behandelt werden. In diesem Abschnitt werden die erforderlichen und optionalen Einstellungen für Barrierefreiheitsdienste erläutert.

Erklärung zu Bedienungshilfen

Damit Ihre App als Bedienungshilfe behandelt wird, fügen Sie in Ihrem Manifest innerhalb des Elements application das Element service anstelle des Elements activity ein. Fügen Sie außerdem im service-Element einen Intent-Filter für den Bedienungshilfe-Dienst ein. Das Manifest muss den Dienst auch schützen, indem die Berechtigung BIND_ACCESSIBILITY_SERVICE hinzugefügt wird, damit nur das System eine Bindung daran vornehmen kann. Beispiel:

  <application>
    <service android:name=".MyAccessibilityService"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
        android:label="@string/accessibility_service_label">
      <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
      </intent-filter>
    </service>
  </application>

Konfiguration von Bedienungshilfen

Barrierefreiheitsdienste müssen eine Konfiguration bereitstellen, in der die Arten von Barrierefreiheitsereignissen angegeben sind, die der Dienst verarbeitet, sowie zusätzliche Informationen zum Dienst. Die Konfiguration eines Bedienungshilfendienstes ist in der Klasse AccessibilityServiceInfo enthalten. Ihr Dienst kann eine Konfiguration mit einer Instanz dieser Klasse und setServiceInfo() zur Laufzeit erstellen und festlegen. Mit dieser Methode sind jedoch nicht alle Konfigurationsoptionen verfügbar.

Sie können in Ihr Manifest ein <meta-data>-Element mit einem Verweis auf eine Konfigurationsdatei einfügen. So können Sie alle Optionen für Ihre Bedienungshilfe festlegen, wie im folgenden Beispiel gezeigt:

<service android:name=".MyAccessibilityService">
  ...
  <meta-data
    android:name="android.accessibilityservice"
    android:resource="@xml/accessibility_service_config" />
</service>

Dieses <meta-data>-Element verweist auf eine XML-Datei, die Sie im Ressourcenverzeichnis Ihrer App erstellen: <project_dir>/res/xml/accessibility_service_config.xml>. Der folgende Code zeigt ein Beispiel für den Inhalt der Dienstkonfigurationsdatei:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_service_description"
    android:packageNames="com.example.android.apis"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagDefault"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
    android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"
/>

Weitere Informationen zu den XML-Attributen, die in der Konfigurationsdatei für den Bedienungshilfe-Dienst verwendet werden können, finden Sie in der folgenden Referenzdokumentation:

Weitere Informationen dazu, welche Konfigurationseinstellungen dynamisch zur Laufzeit festgelegt werden können, finden Sie in der Referenzdokumentation zu AccessibilityServiceInfo.

Bedienungshilfe konfigurieren

Beachten Sie Folgendes, wenn Sie die Konfigurationsvariablen für Ihre Bedienungshilfe festlegen, um dem System mitzuteilen, wie und wann sie ausgeführt werden soll:

  • Auf welche Ereignistypen soll es reagieren?
  • Muss der Dienst für alle Apps oder nur für bestimmte Paketnamen aktiv sein?
  • Welche verschiedenen Arten von Feedback werden verwendet?

Sie haben zwei Möglichkeiten, diese Variablen festzulegen. Die abwärtskompatible Option besteht darin, sie im Code mit setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo) festzulegen. Überschreiben Sie dazu die Methode onServiceConnected() und konfigurieren Sie Ihren Dienst dort, wie im folgenden Beispiel gezeigt:

Kotlin

override fun onServiceConnected() {
    info.apply {
        // Set the type of events that this service wants to listen to. Others
        // aren't passed to this service.
        eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED or AccessibilityEvent.TYPE_VIEW_FOCUSED

        // If you only want this service to work with specific apps, set their
        // package names here. Otherwise, when the service is activated, it
        // listens to events from all apps.
        packageNames = arrayOf("com.example.android.myFirstApp", "com.example.android.mySecondApp")

        // Set the type of feedback your service provides.
        feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN

        // Default services are invoked only if no package-specific services are
        // present for the type of AccessibilityEvent generated. This service is
        // app-specific, so the flag isn't necessary. For a general-purpose
        // service, consider setting the DEFAULT flag.

        // flags = AccessibilityServiceInfo.DEFAULT;

        notificationTimeout = 100
    }

    this.serviceInfo = info

}

Java

@Override
public void onServiceConnected() {
    // Set the type of events that this service wants to listen to. Others
    // aren't passed to this service.
    info.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED |
            AccessibilityEvent.TYPE_VIEW_FOCUSED;

    // If you only want this service to work with specific apps, set their
    // package names here. Otherwise, when the service is activated, it listens
    // to events from all apps.
    info.packageNames = new String[]
            {"com.example.android.myFirstApp", "com.example.android.mySecondApp"};

    // Set the type of feedback your service provides.
    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;

    // Default services are invoked only if no package-specific services are
    // present for the type of AccessibilityEvent generated. This service is
    // app-specific, so the flag isn't necessary. For a general-purpose service,
    // consider setting the DEFAULT flag.

    // info.flags = AccessibilityServiceInfo.DEFAULT;

    info.notificationTimeout = 100;

    this.setServiceInfo(info);

}

Die zweite Option besteht darin, den Dienst über eine XML-Datei zu konfigurieren. Bestimmte Konfigurationsoptionen wie canRetrieveWindowContent sind nur verfügbar, wenn Sie Ihren Dienst mit XML konfigurieren. Die Konfigurationsoptionen aus dem vorherigen Beispiel sehen so aus, wenn sie mit XML definiert werden:

<accessibility-service
     android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
     android:packageNames="com.example.android.myFirstApp, com.example.android.mySecondApp"
     android:accessibilityFeedbackType="feedbackSpoken"
     android:notificationTimeout="100"
     android:settingsActivity="com.example.android.apis.accessibility.TestBackActivity"
     android:canRetrieveWindowContent="true"
/>

Wenn Sie XML verwenden, verweisen Sie im Manifest darauf, indem Sie der Dienstdeklaration ein <meta-data>-Tag hinzufügen, das auf die XML-Datei verweist. Wenn Sie Ihre XML-Datei in res/xml/serviceconfig.xml speichern, sieht das neue Tag so aus:

<service android:name=".MyAccessibilityService">
     <intent-filter>
         <action android:name="android.accessibilityservice.AccessibilityService" />
     </intent-filter>
     <meta-data android:name="android.accessibilityservice"
     android:resource="@xml/serviceconfig" />
</service>

Methoden für Bedienungshilfen

Eine Bedienungshilfe muss die Klasse AccessibilityService erweitern und die folgenden Methoden aus dieser Klasse überschreiben. Diese Methoden werden in der Reihenfolge dargestellt, in der das Android-System sie aufruft: vom Start des Dienstes (onServiceConnected()) über die Laufzeit (onAccessibilityEvent(), onInterrupt()) bis zum Herunterfahren (onUnbind()).

  • onServiceConnected(): (Optional) Das System ruft diese Methode auf, wenn es eine Verbindung zu Ihrem Bedienungshilfe-Dienst herstellt. Mit dieser Methode können Sie einmalige Einrichtungsschritte für Ihren Dienst ausführen, z. B. eine Verbindung zu Diensten für Nutzerfeedback herstellen, etwa zum Audio-Manager oder zum Vibrator des Geräts. Wenn Sie die Konfiguration Ihres Dienstes zur Laufzeit festlegen oder einmalige Anpassungen vornehmen möchten, ist dies ein geeigneter Ort, um setServiceInfo() aufzurufen.

  • onAccessibilityEvent(): (erforderlich) Das System ruft diese Methode zurück, wenn es ein AccessibilityEvent erkennt, das den von Ihrem Bedienungshilfendienst angegebenen Parametern für die Ereignisfilterung entspricht, z. B. wenn der Nutzer auf eine Schaltfläche tippt oder den Fokus auf ein UI-Steuerelement in einer App legt, für die Ihr Bedienungshilfendienst Feedback gibt. Wenn das System diese Methode aufruft, wird die zugehörige AccessibilityEvent übergeben, die der Dienst interpretieren und verwenden kann, um dem Nutzer Feedback zu geben. Diese Methode kann im Laufe des Lebenszyklus Ihres Dienstes mehrmals aufgerufen werden.

  • onInterrupt(): (erforderlich) Das System ruft diese Methode auf, wenn es das Feedback unterbrechen möchte, das Ihr Dienst bereitstellt. Dies geschieht in der Regel als Reaktion auf eine Nutzeraktion, z. B. wenn der Fokus auf ein anderes Steuerelement verschoben wird. Diese Methode kann im Laufe des Lebenszyklus Ihres Dienstes mehrmals aufgerufen werden.

  • onUnbind(): (optional) Das System ruft diese Methode auf, wenn die Bedienungshilfe heruntergefahren wird. Verwenden Sie diese Methode für einmalige Herunterfahrvorgänge, einschließlich der Deaktivierung von Diensten des Nutzerfeedbacks, z. B. des Audio-Managers oder des Gerätevibrators.

Diese Callback-Methoden bilden die grundlegende Struktur für Ihren Barrierefreiheitsdienst. Sie können entscheiden, wie Sie Daten verarbeiten, die vom Android-System in Form von AccessibilityEvent-Objekten bereitgestellt werden, und dem Nutzer Feedback geben. Weitere Informationen zum Abrufen von Informationen aus einem Bedienungshilfenereignis finden Sie unter Ereignisdetails abrufen.

Für Bedienungshilfen-Veranstaltungen registrieren

Eine der wichtigsten Funktionen der Dienstkonfiguration für Bedienungshilfen besteht darin, dass Sie angeben können, welche Arten von Bedienungshilfenereignissen Ihr Dienst verarbeiten kann. Wenn Sie diese Informationen angeben, können Barrierefreiheitsdienste zusammenarbeiten. Außerdem haben Sie die Möglichkeit, nur bestimmte Ereignistypen von bestimmten Apps zu verarbeiten. Die Ereignisfilterung kann die folgenden Kriterien umfassen:

  • Paketnamen:Geben Sie die Paketnamen der Apps an, deren Barrierefreiheitsereignisse von Ihrem Dienst verarbeitet werden sollen. Wenn dieser Parameter nicht angegeben wird, gilt Ihre Bedienungshilfe als für die Verarbeitung von Barrierefreiheitsereignissen für jede App verfügbar. Sie können diesen Parameter in den Konfigurationsdateien der Bedienungshilfe mit dem Attribut android:packageNames als durch Kommas getrennte Liste oder mit dem Member AccessibilityServiceInfo.packageNames festlegen.

  • Ereignistypen:Geben Sie die Arten von Bedienungshilfeereignissen an, die von Ihrem Dienst verarbeitet werden sollen. Sie können diesen Parameter in den Konfigurationsdateien der Bedienungshilfe mit dem Attribut android:accessibilityEventTypes als durch das Zeichen | getrennte Liste festlegen, z. B. accessibilityEventTypes="typeViewClicked|typeViewFocused". Alternativ können Sie sie mit dem AccessibilityServiceInfo.eventTypes-Element festlegen.

Überlegen Sie sich beim Einrichten Ihres Bedienungshilfendienstes genau, welche Ereignisse Ihr Dienst verarbeiten kann, und registrieren Sie sich nur für diese Ereignisse. Da Nutzer mehr als einen Bedienungshilfendienst gleichzeitig aktivieren können, darf Ihr Dienst keine Ereignisse verarbeiten, die er nicht verarbeiten kann. Denken Sie daran, dass andere Dienste diese Ereignisse möglicherweise verarbeiten, um die Nutzerfreundlichkeit zu verbessern.

Lautstärke der Bedienungshilfen

Auf Geräten mit Android 8.0 (API-Level 26) und höher ist die Lautstärkekategorie STREAM_ACCESSIBILITY verfügbar. Damit können Sie die Lautstärke der Audioausgabe Ihres Bedienungshilfendienstes unabhängig von anderen Tönen auf dem Gerät steuern.

Barrierefreiheitsdienste können diesen Streamtyp verwenden, indem sie die Option FLAG_ENABLE_ACCESSIBILITY_VOLUME festlegen. Sie können dann die Lautstärke für Bedienungshilfen des Geräts ändern, indem Sie die Methode adjustStreamVolume() für die Geräteinstanz von AudioManager aufrufen.

Das folgende Code-Snippet zeigt, wie eine Bedienungshilfe die Lautstärkekategorie STREAM_ACCESSIBILITY verwenden kann:

Kotlin

import android.media.AudioManager.*

class MyAccessibilityService : AccessibilityService() {

    private val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager

    override fun onAccessibilityEvent(accessibilityEvent: AccessibilityEvent) {
        if (accessibilityEvent.source.text == "Increase volume") {
            audioManager.adjustStreamVolume(AudioManager.STREAM_ACCESSIBILITY, ADJUST_RAISE, 0)
        }
    }
}

Java

import static android.media.AudioManager.*;

public class MyAccessibilityService extends AccessibilityService {
    private AudioManager audioManager =
            (AudioManager) getSystemService(AUDIO_SERVICE);

    @Override
    public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
        AccessibilityNodeInfo interactedNodeInfo =
                accessibilityEvent.getSource();
        if (interactedNodeInfo.getText().equals("Increase volume")) {
            audioManager.adjustStreamVolume(AudioManager.STREAM_ACCESSIBILITY,
                ADJUST_RAISE, 0);
        }
    }
}

Weitere Informationen finden Sie im Video zur Google I/O 2017 What's new in Android accessibility (Neues zur Barrierefreiheit in Android) ab 6:35.

Kurzbefehl für Bedienungshilfen

Auf Geräten mit Android 8.0 (API-Ebene 26) und höher können Nutzer ihren bevorzugten Bedienungshilfendienst auf jedem Bildschirm aktivieren und deaktivieren, indem sie gleichzeitig beide Lautstärketasten gedrückt halten. Mit dieser Tastenkombination wird TalkBack standardmäßig aktiviert und deaktiviert. Nutzer können die Taste jedoch so konfigurieren, dass sie jeden auf ihrem Gerät installierten Dienst aktiviert und deaktiviert.

Damit Nutzer über die Verknüpfung für Bedienungshilfen auf einen bestimmten Bedienungshilfendienst zugreifen können, muss der Dienst die Funktion zur Laufzeit anfordern.

Weitere Informationen finden Sie im Video zur Google I/O 2017 mit dem Titel What's new in Android accessibility (Neues zur Barrierefreiheit bei Android) ab 13:25.

Schaltfläche "Bedienungshilfen"

Auf Geräten mit einem softwaregerenderten Navigationsbereich und Android 8.0 (API-Level 26) oder höher befindet sich auf der rechten Seite der Navigationsleiste eine Schaltfläche für Bedienungshilfen. Wenn Nutzer diesen Button drücken, können sie je nach Inhalt, der gerade auf dem Display angezeigt wird, eine von mehreren aktivierten Bedienungshilfen und ‑diensten aufrufen.

Damit Nutzer eine bestimmte Bedienungshilfe über den Button „Bedienungshilfen“ aufrufen können, muss der Dienst das Flag FLAG_REQUEST_ACCESSIBILITY_BUTTON im Attribut android:accessibilityFlags eines AccessibilityServiceInfo-Objekts hinzufügen. Der Dienst kann dann Callbacks mit registerAccessibilityButtonCallback() registrieren.

Das folgende Code-Snippet zeigt, wie Sie eine Bedienungshilfe so konfigurieren können, dass sie auf das Drücken des Buttons „Bedienungshilfen“ durch den Nutzer reagiert:

Kotlin

private var mAccessibilityButtonController: AccessibilityButtonController? = null
private var accessibilityButtonCallback:
        AccessibilityButtonController.AccessibilityButtonCallback? = null
private var mIsAccessibilityButtonAvailable: Boolean = false

override fun onServiceConnected() {
    mAccessibilityButtonController = accessibilityButtonController
    mIsAccessibilityButtonAvailable =
            mAccessibilityButtonController?.isAccessibilityButtonAvailable ?: false

    if (!mIsAccessibilityButtonAvailable) return

    serviceInfo = serviceInfo.apply {
        flags = flags or AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON
    }

    accessibilityButtonCallback =
        object : AccessibilityButtonController.AccessibilityButtonCallback() {
            override fun onClicked(controller: AccessibilityButtonController) {
                Log.d("MY_APP_TAG", "Accessibility button pressed!")

                // Add custom logic for a service to react to the
                // accessibility button being pressed.
            }

            override fun onAvailabilityChanged(
                    controller: AccessibilityButtonController,
                    available: Boolean
            ) {
                if (controller == mAccessibilityButtonController) {
                    mIsAccessibilityButtonAvailable = available
                }
            }
    }

    accessibilityButtonCallback?.also {
        mAccessibilityButtonController?.registerAccessibilityButtonCallback(it, null)
    }
}

Java

private AccessibilityButtonController accessibilityButtonController;
private AccessibilityButtonController
        .AccessibilityButtonCallback accessibilityButtonCallback;
private boolean mIsAccessibilityButtonAvailable;

@Override
protected void onServiceConnected() {
    accessibilityButtonController = getAccessibilityButtonController();
    mIsAccessibilityButtonAvailable =
            accessibilityButtonController.isAccessibilityButtonAvailable();

    if (!mIsAccessibilityButtonAvailable) {
        return;
    }

    AccessibilityServiceInfo serviceInfo = getServiceInfo();
    serviceInfo.flags
            |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
    setServiceInfo(serviceInfo);

    accessibilityButtonCallback =
        new AccessibilityButtonController.AccessibilityButtonCallback() {
            @Override
            public void onClicked(AccessibilityButtonController controller) {
                Log.d("MY_APP_TAG", "Accessibility button pressed!");

                // Add custom logic for a service to react to the
                // accessibility button being pressed.
            }

            @Override
            public void onAvailabilityChanged(
              AccessibilityButtonController controller, boolean available) {
                if (controller.equals(accessibilityButtonController)) {
                    mIsAccessibilityButtonAvailable = available;
                }
            }
        };

    if (accessibilityButtonCallback != null) {
        accessibilityButtonController.registerAccessibilityButtonCallback(
                accessibilityButtonCallback, null);
    }
}

Weitere Informationen finden Sie im Video zur Google I/O 2017 mit dem Titel What's new in Android accessibility (Neues zur Barrierefreiheit bei Android) ab 16:28.

Touch-Gesten auf dem Fin­gerabdrucksensor

Bedienungshilfen auf Geräten mit Android 8.0 (API-Ebene 26) und höher können auf Richtungswipes (nach oben, unten, links und rechts) auf dem Fingerabdrucksensor eines Geräts reagieren. Wenn Sie einen Dienst so konfigurieren möchten, dass er Callbacks zu diesen Interaktionen erhält, führen Sie die folgenden Schritte aus:

  1. Deklarieren Sie die Berechtigung USE_BIOMETRIC und die Funktion CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES.
  2. Legen Sie das Flag FLAG_REQUEST_FINGERPRINT_GESTURES im Attribut android:accessibilityFlags fest.
  3. Registrieren Sie sich für Callbacks mit registerFingerprintGestureCallback().

Beachten Sie, dass nicht alle Geräte Fingerabdrucksensoren haben. Verwenden Sie die Methode isHardwareDetected(), um festzustellen, ob ein Gerät den Sensor unterstützt. Auch auf einem Gerät mit Fingerabdrucksensor kann Ihr Dienst den Sensor nicht verwenden, wenn er für die Authentifizierung verwendet wird. Rufen Sie die Methode isGestureDetectionAvailable() auf und implementieren Sie den Callback onGestureDetectionAvailabilityChanged(), um zu ermitteln, wann der Sensor verfügbar ist.

Das folgende Code-Snippet zeigt ein Beispiel für die Verwendung von Fingerabdruckgesten zur Navigation auf einem virtuellen Spielbrett:

// AndroidManifest.xml
<manifest ... >
    <uses-permission android:name="android.permission.USE_FINGERPRINT" />
    ...
    <application>
        <service android:name="com.example.MyFingerprintGestureService" ... >
            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/myfingerprintgestureservice" />
        </service>
    </application>
</manifest>
// myfingerprintgestureservice.xml
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:accessibilityFlags=" ... |flagRequestFingerprintGestures"
    android:canRequestFingerprintGestures="true"
    ... />

Kotlin

// MyFingerprintGestureService.kt
import android.accessibilityservice.FingerprintGestureController.*

class MyFingerprintGestureService : AccessibilityService() {

    private var gestureController: FingerprintGestureController? = null
    private var fingerprintGestureCallback:
            FingerprintGestureController.FingerprintGestureCallback? = null
    private var mIsGestureDetectionAvailable: Boolean = false

    override fun onCreate() {
        gestureController = fingerprintGestureController
        mIsGestureDetectionAvailable = gestureController?.isGestureDetectionAvailable ?: false
    }

    override fun onServiceConnected() {
        if (mFingerprintGestureCallback != null || !mIsGestureDetectionAvailable) return

        fingerprintGestureCallback =
                object : FingerprintGestureController.FingerprintGestureCallback() {
                    override fun onGestureDetected(gesture: Int) {
                        when (gesture) {
                            FINGERPRINT_GESTURE_SWIPE_DOWN -> moveGameCursorDown()
                            FINGERPRINT_GESTURE_SWIPE_LEFT -> moveGameCursorLeft()
                            FINGERPRINT_GESTURE_SWIPE_RIGHT -> moveGameCursorRight()
                            FINGERPRINT_GESTURE_SWIPE_UP -> moveGameCursorUp()
                            else -> Log.e(MY_APP_TAG, "Error: Unknown gesture type detected!")
                        }
                    }

                    override fun onGestureDetectionAvailabilityChanged(available: Boolean) {
                        mIsGestureDetectionAvailable = available
                    }
                }

        fingerprintGestureCallback?.also {
            gestureController?.registerFingerprintGestureCallback(it, null)
        }
    }
}

Java

// MyFingerprintGestureService.java
import static android.accessibilityservice.FingerprintGestureController.*;

public class MyFingerprintGestureService extends AccessibilityService {
    private FingerprintGestureController gestureController;
    private FingerprintGestureController
            .FingerprintGestureCallback fingerprintGestureCallback;
    private boolean mIsGestureDetectionAvailable;

    @Override
    public void onCreate() {
        gestureController = getFingerprintGestureController();
        mIsGestureDetectionAvailable =
                gestureController.isGestureDetectionAvailable();
    }

    @Override
    protected void onServiceConnected() {
        if (fingerprintGestureCallback != null
                || !mIsGestureDetectionAvailable) {
            return;
        }

        fingerprintGestureCallback =
               new FingerprintGestureController.FingerprintGestureCallback() {
            @Override
            public void onGestureDetected(int gesture) {
                switch (gesture) {
                    case FINGERPRINT_GESTURE_SWIPE_DOWN:
                        moveGameCursorDown();
                        break;
                    case FINGERPRINT_GESTURE_SWIPE_LEFT:
                        moveGameCursorLeft();
                        break;
                    case FINGERPRINT_GESTURE_SWIPE_RIGHT:
                        moveGameCursorRight();
                        break;
                    case FINGERPRINT_GESTURE_SWIPE_UP:
                        moveGameCursorUp();
                        break;
                    default:
                        Log.e(MY_APP_TAG,
                                  "Error: Unknown gesture type detected!");
                        break;
                }
            }

            @Override
            public void onGestureDetectionAvailabilityChanged(boolean available) {
                mIsGestureDetectionAvailable = available;
            }
        };

        if (fingerprintGestureCallback != null) {
            gestureController.registerFingerprintGestureCallback(
                    fingerprintGestureCallback, null);
        }
    }
}

Weitere Informationen finden Sie im Video zur Google I/O 2017 mit dem Titel What's new in Android accessibility (Neues zur Barrierefreiheit bei Android) ab Minute 9:03.

Mehrsprachige Sprachausgabe

Ab Android 8.0 (API-Ebene 26) kann der Android-Dienst für die Sprachsynthese (TTS) innerhalb eines einzelnen Textblocks Formulierungen in mehreren Sprachen erkennen und ausgeben. Wenn Sie diese automatische Sprachumschaltung in einer Bedienungshilfe aktivieren möchten, umschließen Sie alle Strings mit LocaleSpan-Objekten, wie im folgenden Code-Snippet gezeigt:

Kotlin

val localeWrappedTextView = findViewById<TextView>(R.id.my_french_greeting_text).apply {
    text = wrapTextInLocaleSpan("Bonjour!", Locale.FRANCE)
}

private fun wrapTextInLocaleSpan(originalText: CharSequence, loc: Locale): SpannableStringBuilder {
    return SpannableStringBuilder(originalText).apply {
        setSpan(LocaleSpan(loc), 0, originalText.length - 1, 0)
    }
}

Java

TextView localeWrappedTextView = findViewById(R.id.my_french_greeting_text);
localeWrappedTextView.setText(wrapTextInLocaleSpan("Bonjour!", Locale.FRANCE));

private SpannableStringBuilder wrapTextInLocaleSpan(
        CharSequence originalText, Locale loc) {
    SpannableStringBuilder myLocaleBuilder =
            new SpannableStringBuilder(originalText);
    myLocaleBuilder.setSpan(new LocaleSpan(loc), 0,
            originalText.length() - 1, 0);
    return myLocaleBuilder;
}

Weitere Informationen finden Sie im Video zur Google I/O 2017 mit dem Titel What's new in Android accessibility (Neues zur Barrierefreiheit bei Android) ab Minute 10:59.

Im Namen von Nutzern handeln

Seit 2011 können Bedienungshilfen im Namen von Nutzern agieren, z. B. den Eingabefokus ändern und Benutzeroberflächenelemente auswählen (aktivieren). 2012 wurde das Angebot an Aktionen erweitert, sodass nun auch das Scrollen von Listen und die Interaktion mit Textfeldern möglich war. Bedienungshilfen können auch globale Aktionen ausführen, z. B. zum Startbildschirm wechseln, den Button „Zurück“ drücken und den Benachrichtigungsbildschirm und die Liste der zuletzt verwendeten Apps öffnen. Seit 2012 bietet Android den Fokus für Barrierefreiheit, mit dem alle sichtbaren Elemente von einer Bedienungshilfe ausgewählt werden können.

Mit diesen Funktionen können Entwickler von Bedienungshilfen alternative Navigationsmodi wie die Bedienung über Gesten erstellen und Nutzern mit Behinderungen eine bessere Steuerung ihrer Android-Geräte ermöglichen.

Auf Gesten achten

Barrierefreiheitsdienste können auf bestimmte Gesten reagieren und im Namen eines Nutzers Aktionen ausführen. Für diese Funktion muss Ihre Bedienungshilfe die Aktivierung der Funktion „Mit Berührung erkunden“ anfordern. Ihr Dienst kann diese Aktivierung anfordern, indem er das flags-Element der AccessibilityServiceInfo-Instanz des Dienstes auf FLAG_REQUEST_TOUCH_EXPLORATION_MODE setzt, wie im folgenden Beispiel gezeigt.

Kotlin

class MyAccessibilityService : AccessibilityService() {

    override fun onCreate() {
        serviceInfo.flags = AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE
    }
    ...
}

Java

public class MyAccessibilityService extends AccessibilityService {
    @Override
    public void onCreate() {
        getServiceInfo().flags = AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
    }
    ...
}

Nachdem Ihr Dienst die Aktivierung von „Mit Berührung erkunden“ angefordert hat, muss der Nutzer die Funktion aktivieren, falls sie noch nicht aktiv ist. Wenn diese Funktion aktiv ist, erhält Ihr Dienst Benachrichtigungen zu Bedienungshilfengebärden über die onGesture()-Callback-Methode Ihres Dienstes und kann im Namen des Nutzers darauf reagieren.

Fortgesetzte Gesten

Geräte mit Android 8.0 (API-Level 26) und höher unterstützen fortgesetzte Gesten oder programmatische Gesten, die mehr als ein Path-Objekt enthalten.

Wenn Sie eine Folge von Strichen angeben, können Sie mit dem letzten Argument willContinue im Konstruktor GestureDescription.StrokeDescription angeben, dass sie zur selben programmatischen Geste gehören, wie im folgenden Code-Snippet gezeigt:

Kotlin

// Simulates an L-shaped drag path: 200 pixels right, then 200 pixels down.
private fun doRightThenDownDrag() {
    val dragRightPath = Path().apply {
        moveTo(200f, 200f)
        lineTo(400f, 200f)
    }
    val dragRightDuration = 500L // 0.5 second

    // The starting point of the second path must match
    // the ending point of the first path.
    val dragDownPath = Path().apply {
        moveTo(400f, 200f)
        lineTo(400f, 400f)
    }
    val dragDownDuration = 500L
    val rightThenDownDrag = GestureDescription.StrokeDescription(
            dragRightPath,
            0L,
            dragRightDuration,
            true
    ).apply {
        continueStroke(dragDownPath, dragRightDuration, dragDownDuration, false)
    }
}

Java

// Simulates an L-shaped drag path: 200 pixels right, then 200 pixels down.
private void doRightThenDownDrag() {
    Path dragRightPath = new Path();
    dragRightPath.moveTo(200, 200);
    dragRightPath.lineTo(400, 200);
    long dragRightDuration = 500L; // 0.5 second

    // The starting point of the second path must match
    // the ending point of the first path.
    Path dragDownPath = new Path();
    dragDownPath.moveTo(400, 200);
    dragDownPath.lineTo(400, 400);
    long dragDownDuration = 500L;
    GestureDescription.StrokeDescription rightThenDownDrag =
            new GestureDescription.StrokeDescription(dragRightPath, 0L,
            dragRightDuration, true);
    rightThenDownDrag.continueStroke(dragDownPath, dragRightDuration,
            dragDownDuration, false);
}

Weitere Informationen finden Sie im Video zur Google I/O 2017 What's new in Android accessibility (Neues zur Barrierefreiheit bei Android) ab 15:47.

Aktionen für Bedienungshilfen verwenden

Bedienungshilfen können im Namen von Nutzern agieren, um die Interaktion mit Apps zu vereinfachen und die Produktivität zu steigern. Die Möglichkeit von Bedienungshilfen, Aktionen auszuführen, wurde 2011 hinzugefügt und 2012 erheblich erweitert.

Damit Ihre Bedienungshilfe im Namen von Nutzern agieren kann, muss sie registriert werden, um Ereignisse von Apps zu empfangen und die Berechtigung zum Anzeigen des Inhalts von Apps anzufordern. Dazu muss android:canRetrieveWindowContent in der Dienstkonfigurationsdatei auf true gesetzt werden. Wenn Ihr Dienst Ereignisse empfängt, kann er das AccessibilityNodeInfo-Objekt aus dem Ereignis mit getSource() abrufen. Mit dem AccessibilityNodeInfo-Objekt kann Ihr Dienst dann die Ansichtshierarchie durchsuchen, um zu ermitteln, welche Aktion ausgeführt werden soll, und dann mit performAction() für den Nutzer handeln.

Kotlin

class MyAccessibilityService : AccessibilityService() {

    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        // Get the source node of the event.
        event.source?.apply {

            // Use the event and node information to determine what action to
            // take.

            // Act on behalf of the user.
            performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)

            // Recycle the nodeInfo object.
            recycle()
        }
    }
    ...
}

Java

public class MyAccessibilityService extends AccessibilityService {

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        // Get the source node of the event.
        AccessibilityNodeInfo nodeInfo = event.getSource();

        // Use the event and node information to determine what action to take.

        // Act on behalf of the user.
        nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);

        // Recycle the nodeInfo object.
        nodeInfo.recycle();
    }
    ...
}

Mit der Methode performAction() kann Ihr Dienst Aktionen in einer App ausführen. Wenn Ihr Dienst eine globale Aktion ausführen muss, z. B. zum Startbildschirm wechseln, den Button „Zurück“ drücken oder den Benachrichtigungsbildschirm oder die Liste der zuletzt verwendeten Apps öffnen, verwenden Sie die Methode performGlobalAction().

Fokustypen verwenden

2012 wurde in Android ein Fokus für die Benutzeroberfläche namens Fokus für Bedienungshilfen eingeführt. Bedienungshilfen können diesen Fokus verwenden, um ein beliebiges sichtbares Element der Benutzeroberfläche auszuwählen und darauf zu reagieren. Dieser Fokustyp unterscheidet sich vom Eingabefokus, der bestimmt, welches Benutzeroberflächenelement auf dem Bildschirm Eingaben empfängt, wenn ein Nutzer Zeichen eingibt, die Eingabetaste auf einer Tastatur drückt oder die mittlere Taste eines Steuerkreuzes drückt.

Es ist möglich, dass ein Element in einer Benutzeroberfläche den Eingabefokus hat, während ein anderes Element den Fokus für Bedienungshilfen hat. Der Zweck des Bedienungshilfen-Fokus besteht darin, Bedienungshilfen eine Methode zur Interaktion mit sichtbaren Elementen auf einem Bildschirm zu bieten, unabhängig davon, ob das Element aus Systemsicht eingabefähig ist. Damit Ihre Bedienungshilfe korrekt mit den Eingabeelementen von Apps interagiert, sollten Sie die Richtlinien zum Testen der Barrierefreiheit einer App befolgen, um Ihren Dienst mit einer typischen App zu testen.

Ein Bedienungshilfendienst kann mit der Methode AccessibilityNodeInfo.findFocus() ermitteln, welches Benutzeroberflächenelement den Eingabefokus oder den Bedienungshilfenfokus hat. Sie können auch mit der Methode focusSearch() nach Elementen suchen, die mit dem Eingabefokus ausgewählt werden können. Schließlich kann Ihr Bedienungshilfen-Dienst den Fokus für Bedienungshilfen mit der Methode performAction(AccessibilityNodeInfo.ACTION_SET_ACCESSIBILITY_FOCUS) festlegen.

Informationen sammeln

Barrierefreiheitsdienste haben Standardmethoden zum Erfassen und Darstellen wichtiger Einheiten von von Nutzern bereitgestellten Informationen, z. B. Termindetails, Text und Zahlen.

Details zu Fensteränderungen abrufen

Unter Android 9 (API-Level 28) und höher können Apps Fensteraktualisierungen nachverfolgen, wenn mehrere Fenster gleichzeitig neu gezeichnet werden. Wenn ein TYPE_WINDOWS_CHANGED-Ereignis eintritt, verwenden Sie die getWindowChanges() API, um zu ermitteln, wie sich die Fenster ändern. Bei einer Aktualisierung im Mehrfenstermodus wird für jedes Fenster eine eigene Gruppe von Ereignissen generiert. Die Methode getSource() gibt die Stammansicht des Fensters zurück, das mit jedem Ereignis verknüpft ist.

Wenn eine App Titel für Bedienungshilfen für ihre View-Objekte definiert, kann Ihr Dienst erkennen, wenn die Benutzeroberfläche der App aktualisiert wird. Wenn ein TYPE_WINDOW_STATE_CHANGED-Ereignis eintritt, verwenden Sie die von getContentChangeTypes() zurückgegebenen Typen, um zu bestimmen, wie sich das Fenster ändert. Das Framework kann beispielsweise erkennen, wenn ein Bereich einen neuen Titel erhält oder verschwindet.

Termindetails abrufen

Android stellt Informationen zur Interaktion mit der Benutzeroberfläche über AccessibilityEvent-Objekte für Dienste zur Barrierefreiheit bereit. In früheren Android-Versionen enthielten Bedienungshilfe-Ereignisse zwar wichtige Details zur vom Nutzer ausgewählten Benutzeroberflächensteuerung, aber nur wenige Kontextinformationen. In vielen Fällen sind diese fehlenden Kontextinformationen entscheidend, um die Bedeutung der ausgewählten Kontrollvariablen zu verstehen.

Ein Beispiel für eine Benutzeroberfläche, in der der Kontext entscheidend ist, ist ein Kalender oder Tagesplaner. Wenn der Nutzer in einer Liste von Montag bis Freitag einen Zeitraum um 16:00 Uhr auswählt und die Bedienungshilfe „16:00 Uhr“ ansagt, aber nicht den Namen des Wochentags, den Tag des Monats oder den Namen des Monats, ist das Feedback verwirrend. In diesem Fall ist der Kontext eines Steuerelements der Benutzeroberfläche für einen Nutzer, der eine Besprechung planen möchte, von entscheidender Bedeutung.

Seit 2011 erweitert Android die Menge an Informationen, die ein Barrierefreiheitsdienst über eine Benutzeroberflächeninteraktion erhalten kann, erheblich, indem Barrierefreiheitsereignisse auf Grundlage der Ansichtshierarchie zusammengestellt werden. Eine Ansichtshierarchie ist die Menge der Benutzeroberflächenkomponenten, die die Komponente (ihre übergeordneten Elemente) und die Benutzeroberflächenelemente enthalten, die von dieser Komponente enthalten sein können (ihre untergeordneten Elemente). So kann Android detailliertere Informationen zu Bedienungshilfenereignissen bereitstellen, sodass Bedienungshilfen Nutzern nützlicheres Feedback geben können.

Eine Bedienungshilfe erhält Informationen zu einem Benutzeroberflächenereignis über ein AccessibilityEvent, das vom System an die onAccessibilityEvent()-Callback-Methode des Dienstes übergeben wird. Dieses Objekt enthält Details zum Ereignis, z. B. den Typ des Objekts, auf das sich die Aktion bezieht, den beschreibenden Text und andere Details.

  • AccessibilityEvent.getRecordCount() und getRecord(int): Mit diesen Methoden können Sie die Gruppe von AccessibilityRecord-Objekten abrufen, die zum AccessibilityEvent beitragen, das Ihnen vom System übergeben wird. Dieser Detaillierungsgrad bietet mehr Kontext für das Ereignis, das Ihre Bedienungshilfe auslöst.

  • AccessibilityRecord.getSource(): Diese Methode gibt ein AccessibilityNodeInfo-Objekt zurück. Mit diesem Objekt können Sie die Hierarchie des Ansichtslayouts (über- und untergeordnete Elemente) der Komponente anfordern, aus der das Barrierefreiheitsereignis stammt. Mit dieser Funktion kann ein Bedienungshilfendienst den vollständigen Kontext eines Ereignisses untersuchen, einschließlich des Inhalts und des Status aller umschließenden oder untergeordneten Ansichten.

festlegt.

Die Android-Plattform bietet die Möglichkeit, dass ein AccessibilityService die Ansichtshierarchie abfragt und Informationen zur UI-Komponente erfasst, die ein Ereignis generiert, sowie zu deren über- und untergeordneten Elementen. Dazu legen Sie die folgende Zeile in Ihrer XML-Konfiguration fest:

android:canRetrieveWindowContent="true"

Rufen Sie anschließend mit getSource() ein AccessibilityNodeInfo-Objekt ab. Bei diesem Aufruf wird nur ein Objekt zurückgegeben, wenn das Fenster, in dem das Ereignis stattfindet, noch das aktive Fenster ist. Andernfalls wird „null“ zurückgegeben.

Im folgenden Beispiel wird durch den Code bei Empfang eines Ereignisses Folgendes ausgeführt:

  1. Ruft sofort das übergeordnete Element der Ansicht ab, aus der das Ereignis stammt.
  2. Suchen Sie in dieser Ansicht nach einem Label und einem Kästchen als untergeordnete Ansichten.
  3. Wenn sie gefunden werden, wird ein String erstellt, der dem Nutzer gemeldet wird und das Label und den Status der Überprüfung angibt.

Wenn beim Durchlaufen der Ansichtshierarchie ein Nullwert zurückgegeben wird, wird die Methode beendet.

Kotlin

// Alternative onAccessibilityEvent that uses AccessibilityNodeInfo.

override fun onAccessibilityEvent(event: AccessibilityEvent) {

    val source: AccessibilityNodeInfo = event.source ?: return

    // Grab the parent of the view that fires the event.
    val rowNode: AccessibilityNodeInfo = getListItemNodeInfo(source) ?: return

    // Using this parent, get references to both child nodes, the label, and the
    // checkbox.
    val taskLabel: CharSequence = rowNode.getChild(0)?.text ?: run {
        rowNode.recycle()
        return
    }

    val isComplete: Boolean = rowNode.getChild(1)?.isChecked ?: run {
        rowNode.recycle()
        return
    }

    // Determine what the task is and whether it's complete based on the text
    // inside the label, and the state of the checkbox.
    if (rowNode.childCount < 2 || !rowNode.getChild(1).isCheckable) {
        rowNode.recycle()
        return
    }

    val completeStr: String = if (isComplete) {
        getString(R.string.checked)
    } else {
        getString(R.string.not_checked)
    }
    val reportStr = "$taskLabel$completeStr"
    speakToUser(reportStr)
}

Java

// Alternative onAccessibilityEvent that uses AccessibilityNodeInfo.

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

    AccessibilityNodeInfo source = event.getSource();
    if (source == null) {
        return;
    }

    // Grab the parent of the view that fires the event.
    AccessibilityNodeInfo rowNode = getListItemNodeInfo(source);
    if (rowNode == null) {
        return;
    }

    // Using this parent, get references to both child nodes, the label, and the
    // checkbox.
    AccessibilityNodeInfo labelNode = rowNode.getChild(0);
    if (labelNode == null) {
        rowNode.recycle();
        return;
    }

    AccessibilityNodeInfo completeNode = rowNode.getChild(1);
    if (completeNode == null) {
        rowNode.recycle();
        return;
    }

    // Determine what the task is and whether it's complete based on the text
    // inside the label, and the state of the checkbox.
    if (rowNode.getChildCount() < 2 || !rowNode.getChild(1).isCheckable()) {
        rowNode.recycle();
        return;
    }

    CharSequence taskLabel = labelNode.getText();
    final boolean isComplete = completeNode.isChecked();
    String completeStr = null;

    if (isComplete) {
        completeStr = getString(R.string.checked);
    } else {
        completeStr = getString(R.string.not_checked);
    }
    String reportStr = taskLabel + completeStr;
    speakToUser(reportStr);
}

Sie haben jetzt einen vollständigen, funktionierenden Bedienungshilfendienst. Sie können konfigurieren, wie die App mit dem Nutzer interagiert, indem Sie die Sprachausgabe-Engine von Android hinzufügen oder ein Vibrator verwenden, um haptisches Feedback zu geben.

Text verarbeiten

Auf Geräten mit Android 8.0 (API-Level 26) und höher sind mehrere Textverarbeitungsfunktionen verfügbar, die es Bedienungshilfen erleichtern, bestimmte Texteinheiten auf dem Bildschirm zu erkennen und zu bearbeiten.

Kurzinfos

Mit Android 9 (API-Level 28) werden mehrere Funktionen eingeführt, mit denen Sie in der Benutzeroberfläche einer App auf Kurzinfos zugreifen können. Verwenden Sie getTooltipText(), um den Text einer Kurzinfo zu lesen, und ACTION_SHOW_TOOLTIP und ACTION_HIDE_TOOLTIP, um Instanzen von View anzuweisen, ihre Kurzinfos ein- oder auszublenden.

Hinweistext

Seit 2017 bietet Android mehrere Methoden zum Interagieren mit dem Hinweistext eines textbasierten Objekts:

  • Mit den Methoden isShowingHintText() und setShowingHintText() wird angegeben bzw. festgelegt, ob der aktuelle Textinhalt des Knotens den Hinweistext des Knotens darstellt.
  • getHintText() bietet Zugriff auf den Hinweistext selbst. Auch wenn für ein Objekt kein Hinweis angezeigt wird, kann getHintText() aufgerufen werden.

Positionen von Bildschirmtextzeichen

Auf Geräten mit Android 8.0 (API-Ebene 26) und höher können Barrierefreiheitsdienste die Bildschirmkoordinaten für das umgebende Rechteck jedes sichtbaren Zeichens in einem TextView-Widget ermitteln. Dienste rufen diese Koordinaten ab, indem sie refreshWithExtraData() aufrufen und EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY als erstes Argument und ein Bundle-Objekt als zweites Argument übergeben. Während die Methode ausgeführt wird, füllt das System das Bundle-Argument mit einem parcelable-Array von Rect-Objekten. Jedes Rect-Objekt stellt den Begrenzungsrahmen eines bestimmten Zeichens dar.

Standardisierte einseitige Bereichswerte

Einige AccessibilityNodeInfo-Objekte verwenden eine Instanz von AccessibilityNodeInfo.RangeInfo, um anzugeben, dass ein UI-Element einen Wertebereich annehmen kann. Wenn Sie einen Bereich mit RangeInfo.obtain() erstellen oder die Extremwerte des Bereichs mit getMin() und getMax() abrufen, beachten Sie, dass Geräte mit Android 8.0 (API-Level 26) und höher einseitige Bereiche standardisiert darstellen:

Auf Bedienungshilfenereignisse reagieren

Nachdem Ihr Dienst für die Ausführung und das Abhören von Ereignissen eingerichtet ist, schreiben Sie Code, damit er weiß, was zu tun ist, wenn ein AccessibilityEvent eingeht. Überschreiben Sie zuerst die Methode onAccessibilityEvent(AccessibilityEvent). Verwenden Sie in dieser Methode getEventType(), um den Ereignistyp zu bestimmen, und getContentDescription(), um den Labeltext zu extrahieren, der mit der Ansicht verknüpft ist, die das Ereignis auslöst:

Kotlin

override fun onAccessibilityEvent(event: AccessibilityEvent) {
    var eventText: String = when (event.eventType) {
        AccessibilityEvent.TYPE_VIEW_CLICKED -> "Clicked: "
        AccessibilityEvent.TYPE_VIEW_FOCUSED -> "Focused: "
        else -> ""
    }

    eventText += event.contentDescription

    // Do something nifty with this text, like speak the composed string back to
    // the user.
    speakToUser(eventText)
    ...
}

Java

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    final int eventType = event.getEventType();
    String eventText = null;
    switch(eventType) {
        case AccessibilityEvent.TYPE_VIEW_CLICKED:
            eventText = "Clicked: ";
            break;
        case AccessibilityEvent.TYPE_VIEW_FOCUSED:
            eventText = "Focused: ";
            break;
    }

    eventText = eventText + event.getContentDescription();

    // Do something nifty with this text, like speak the composed string back to
    // the user.
    speakToUser(eventText);
    ...
}

Zusätzliche Ressourcen

Weitere Informationen finden Sie in den folgenden Ressourcen:

Leitfäden

Codelabs