Eigene Bedienungshilfe erstellen

Ein Bedienungshilfen-Dienst ist eine App zur Optimierung der Benutzeroberfläche, um Nutzer mit Behinderungen oder Nutzern, die vorübergehend nicht vollständig mit einem Gerät interagieren können, zu unterstützen. Beispielsweise benötigen Nutzer, die Auto fahren, sich um ein Kleinkind kümmern oder an einer lauten Party teilnehmen, möglicherweise zusätzliches oder alternatives Feedback über die Benutzeroberfläche.

Android bietet standardmäßige Bedienungshilfen wie TalkBack. Entwickler können ihre eigenen Dienste erstellen und vertreiben. In diesem Dokument werden die Grundlagen zum Erstellen einer Bedienungshilfe erläutert.

Eine 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 identisch.

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 damit keine Anwendung verknüpfen möchten, können Sie die Startklasse Activity aus der Quelle entfernen.

Manifestdeklarationen und Berechtigungen

Apps, die Bedienungshilfen anbieten, müssen im App-Manifest bestimmte Deklarationen enthalten, damit sie vom Android-System als Bedienungshilfe behandelt werden. In diesem Abschnitt werden die erforderlichen und optionalen Einstellungen für Bedienungshilfen beschrieben.

Erklärung zum Dienst „Barrierefreiheit im Internet“

Damit Ihre App als Bedienungshilfe behandelt wird, muss ein service-Element anstelle des activity-Elements in das application-Element Ihres Manifests eingefügt werden. Fügen Sie außerdem innerhalb des service-Elements einen Intent-Filter für den Bedienungshilfendienst hinzu. Das Manifest muss den Dienst außerdem schützen. Dazu wird die Berechtigung BIND_ACCESSIBILITY_SERVICE hinzugefügt, damit nur das System eine Bindung an ihn 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 der Bedienungshilfen

Bedienungshilfen müssen eine Konfiguration bereitstellen, in der die Arten von Bedienungshilfen-Ereignissen, die der Dienst verarbeitet, sowie zusätzliche Informationen zum Dienst angegeben sind. Die Konfiguration einer Bedienungshilfe ist in der Klasse AccessibilityServiceInfo enthalten. Ihr Dienst kann eine Konfiguration mithilfe einer Instanz dieser Klasse und setServiceInfo() zur Laufzeit erstellen und festlegen. Bei 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, mit der Sie alle Optionen für den Bedienungshilfen-Dienst festlegen können, 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 Anwendung 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 des Bedienungshilfendiensts verwendet werden können, finden Sie in der folgenden Referenzdokumentation:

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

Bedienungshilfe konfigurieren

Beachten Sie Folgendes, wenn Sie die Konfigurationsvariablen für den Bedienungshilfendienst festlegen, um dem System mitzuteilen, wie und wann es ausgeführt werden soll:

  • Auf welche Ereignistypen soll er reagieren?
  • Muss der Dienst für alle Anwendungen oder nur für bestimmte Paketnamen aktiv sein?
  • Welche verschiedenen Feedbacktypen werden dabei 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 den 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 Möglichkeit besteht darin, den Dienst mithilfe einer 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 bei der Definition mit XML so aus:

<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 in Ihrem Manifest darauf, indem Sie in Ihre Dienstdeklaration ein <meta-data>-Tag einfügen, das auf die XML-Datei verweist. Wenn du deine XML-Datei in res/xml/serviceconfig.xml speicherst, 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-Dienste

Eine Bedienungshilfe muss die Klasse AccessibilityService erweitern und die folgenden Methoden aus dieser Klasse überschreiben. Diese Methoden werden in der Reihenfolge angezeigt, in der sie vom Android-System aufgerufen werden: vom Start des Dienstes (onServiceConnected()) über seine Ausführung (onAccessibilityEvent(), onInterrupt()) bis zum Zeitpunkt seiner Beendigung (onUnbind()).

  • onServiceConnected(): (optional) Das System ruft diese Methode auf, wenn eine Verbindung zu Ihrer Bedienungshilfe hergestellt wird. Verwenden Sie diese Methode, um einmalige Einrichtungsschritte für Ihren Dienst auszuführen, einschließlich der Verbindung mit Nutzerfeedback-Systemdiensten wie dem Audiomanager oder der Gerätevibrator. 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 eine AccessibilityEvent erkennt, die den von Ihrem Bedienungshilfendienst angegebenen Ereignisfilterparametern entspricht, z. B. wenn der Nutzer auf eine Schaltfläche tippt oder den Fokus auf eine UI-Steuerung in einer App legt, für die die Bedienungshilfe Feedback gibt. Wenn das System diese Methode aufruft, wird das zugehörige AccessibilityEvent-Element übergeben, das der Dienst dann interpretieren und verwenden kann, um dem Nutzer Feedback zu geben. Diese Methode kann während des Lebenszyklus Ihres Dienstes mehrmals aufgerufen werden.

  • onInterrupt() (erforderlich): Das System ruft diese Methode auf, wenn das Feedback vom Dienst unterbrochen werden soll, in der Regel als Reaktion auf eine Nutzeraktion wie das Verschieben des Fokus auf ein anderes Steuerelement. Diese Methode kann während des Lebenszyklus Ihres Dienstes mehrmals aufgerufen werden.

  • onUnbind(): (optional) Das System ruft diese Methode auf, wenn das System die Bedienungshilfe herunterfährt. Verwenden Sie diese Methode, um ein einmaliges Herunterfahren auszuführen, einschließlich des Aufhebens der Zuweisung von Nutzerfeedback-Systemdiensten wie dem Audio-Manager oder der Gerätevibratorfunktion.

Diese Callback-Methoden stellen die Grundstruktur für Ihren Bedienungshilfedienst bereit. Du kannst entscheiden, wie die vom Android-System in Form von AccessibilityEvent-Objekten bereitgestellten Daten verarbeitet werden sollen, und dem Nutzer Feedback geben. Weitere Informationen zum Abrufen von Informationen zu Bedienungshilfen-Terminen finden Sie unter Termindetails abrufen.

Für Veranstaltungen zur Barrierefreiheit registrieren

Eine der wichtigsten Funktionen der Konfigurationsparameter des Bedienungshilfendienstes besteht darin, anzugeben, welche Arten von Bedienungshilfen-Ereignissen Ihr Dienst verarbeiten kann. Wenn Sie diese Informationen angeben, können Bedienungshilfen miteinander zusammenarbeiten und Sie können flexibel nur bestimmte Ereignistypen aus bestimmten Apps verarbeiten. Die Ereignisfilterung kann die folgenden Kriterien umfassen:

  • Paketnamen:Geben Sie die Paketnamen der Apps an, deren Bedienungshilfen-Ereignisse Ihr Dienst verarbeiten soll. Wenn Sie diesen Parameter nicht angeben, wird der Bedienungshilfendienst für Bedienungshilfen-Ereignisse aller Apps als verfügbar angesehen. Sie können diesen Parameter in den Konfigurationsdateien des Bedienungshilfendiensts mit dem Attribut android:packageNames als durch Kommas getrennte Liste festlegen oder das Mitglied AccessibilityServiceInfo.packageNames verwenden.

  • Ereignistypen:Geben Sie die Typen von Bedienungshilfen an, die der Dienst verarbeiten soll. Sie können diesen Parameter in den Konfigurationsdateien des Bedienungshilfendiensts mit dem Attribut android:accessibilityEventTypes als Liste festlegen, die durch das Zeichen | getrennt ist, z. B. accessibilityEventTypes="typeViewClicked|typeViewFocused". Alternativ können Sie ihn mit dem Element AccessibilityServiceInfo.eventTypes festlegen.

Überlegen Sie sich beim Einrichten der Bedienungshilfe genau, welche Ereignisse Ihr Dienst verarbeiten kann, und registrieren Sie sich nur für diese Ereignisse. Da Nutzer mehrere Bedienungshilfen gleichzeitig aktivieren können, darf der Dienst keine Ereignisse verarbeiten, die er nicht verarbeiten kann. Denken Sie daran, dass andere Dienste diese Ereignisse verarbeiten können, um die User Experience zu verbessern.

Lautstärke der Bedienungshilfen

Geräte mit Android 8.0 (API-Level 26) und höher enthalten die Lautstärkekategorie STREAM_ACCESSIBILITY. Damit kannst du die Lautstärke der Audioausgabe deines Bedienungshilfendienstes unabhängig von anderen Tönen auf dem Gerät steuern.

Bedienungshilfen können diesen Streamtyp durch Festlegen der Option FLAG_ENABLE_ACCESSIBILITY_VOLUME verwenden. Anschließend können Sie die Lautstärke der Bedienungshilfen des Geräts ändern, indem Sie die Methode adjustStreamVolume() in der AudioManager-Instanz des Geräts aufrufen.

Das folgende Code-Snippet zeigt, wie eine Bedienungshilfe die Volume-Kategorie 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 der Session What's new in Android Accessibility von der Google I/O 2017 ab 6:35 Uhr.

Kurzbefehl für Bedienungshilfen

Auf Geräten mit Android 8.0 (API-Level 26) und höher können Nutzer ihre bevorzugte Bedienungshilfe auf jedem Bildschirm aktivieren und deaktivieren, indem sie beide Lautstärketasten gleichzeitig gedrückt halten. Durch diese Verknüpfung wird TalkBack standardmäßig aktiviert und deaktiviert. Nutzer können die Schaltfläche jedoch so konfigurieren, dass alle auf ihrem Gerät installierten Dienste aktiviert und deaktiviert werden.

Damit Nutzer über die Bedienungshilfenverknüpfung auf eine bestimmte Bedienungshilfe zugreifen können, muss der Dienst die Funktion zur Laufzeit anfordern.

Weitere Informationen finden Sie im Video der Session What's new in Android Accessibility von der Google I/O 2017 ab 13:25 Uhr.

Schaltfläche „Bedienungshilfen“

Auf Geräten mit einem als Software gerenderten Navigationsbereich und Android 8.0 (API-Level 26) oder höher enthält die rechte Seite der Navigationsleiste eine Schaltfläche für Bedienungshilfen. Wenn Nutzer auf diese Schaltfläche klicken, können sie eine von mehreren aktivierten Bedienungshilfen und -diensten aufrufen, je nachdem, welche Inhalte gerade auf dem Bildschirm angezeigt werden.

Damit Nutzer eine bestimmte Bedienungshilfe über die entsprechende Schaltfläche aufrufen können, muss der Dienst das Flag FLAG_REQUEST_ACCESSIBILITY_BUTTON in das Attribut android:accessibilityFlags des AccessibilityServiceInfo-Objekts einfügen. Der Dienst kann dann Callbacks mit registerAccessibilityButtonCallback() registrieren.

Das folgende Code-Snippet zeigt, wie Sie eine Bedienungshilfe konfigurieren können, die reagiert, wenn der Nutzer auf die Schaltfläche „Bedienungshilfen“ drückt:

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 der Session What's new in Android Accessibility von der Google I/O 2017 ab 16:28 Uhr.

Gesten auf dem Fin­gerabdrucksensor

Auf Geräten mit Android 8.0 (API-Level 26) und höher können Bedienungshilfen auf Wischbewegungen (nach oben, unten, links und rechts) entlang des Fingerabdrucksensors eines Geräts reagieren. Führen Sie die folgende Reihenfolge aus, um einen Dienst für den Empfang von Callbacks zu diesen Interaktionen zu konfigurieren:

  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 mit registerFingerprintGestureCallback() für Rückrufe.

Bitte beachte, dass nicht alle Geräte Fingerabdrucksensoren haben. Mit der Methode isHardwareDetected() kannst du feststellen, ob ein Gerät den Sensor unterstützt. Selbst auf einem Gerät mit Fingerabdrucksensor kann Ihr Dienst den Sensor nicht verwenden, wenn er zu Authentifizierungszwecken verwendet wird. Wenn Sie wissen möchten, wann der Sensor verfügbar ist, rufen Sie die Methode isGestureDetectionAvailable() auf und implementieren Sie den onGestureDetectionAvailabilityChanged()-Callback.

Das folgende Code-Snippet zeigt ein Beispiel für die Verwendung von Fingerabdruckgesten, um ein virtuelles Spielbrett zu navigieren:

// 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 der Session What's new in Android Accessibility von der Google I/O 2017 ab 9:03 Uhr.

Mehrsprachige Sprachausgabe

Ab Android 8.0 (API-Ebene 26) kann der Sprachausgabe-Dienst (TTS) von Android Wortgruppen in mehreren Sprachen in einem einzigen Textblock identifizieren und sprechen. Um diese Funktion zur automatischen Sprachwechselfunktion in einem Bedienungshilfedienst zu aktivieren, umschließen Sie alle Strings in 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 der Session What's new in Android Accessibility von der Google I/O 2017 ab 10:59 Uhr.

Im Namen von Nutzern handeln

Seit 2011 können Bedienungshilfen im Namen von Nutzern agieren. Dazu gehören das Ändern des Eingabefokus und das Auswählen (Aktivieren) von Elementen der Benutzeroberfläche. 2012 wurde der Aktionsbereich um das Scrollen von Listen und das Interagieren mit Textfeldern erweitert. Bedienungshilfen können auch globale Aktionen ausführen, z. B. den Startbildschirm aufrufen, die Schaltfläche „Zurück“ drücken und den Benachrichtigungsbildschirm und die Liste der zuletzt verwendeten Apps öffnen. Seit 2012 hat Android den Schwerpunkt für Barrierefreiheit, sodass alle sichtbaren Elemente über einen Bedienungshilfendienst ausgewählt werden können.

Mit diesen Funktionen können Entwickler von Bedienungshilfen alternative Navigationsmodi wie die Bedienung über Gesten erstellen und Nutzer mit Behinderungen können ihre Android-Mobilgeräte besser steuern.

Auf Gesten achten

Bedienungshilfen können auf bestimmte Gesten reagieren und im Namen eines Nutzers reagieren. Für diese Funktion muss die Bedienungshilfe die Funktion „Tippen & Entdecken“ aktivieren. Ihr Dienst kann diese Aktivierung anfordern. Dazu setzt er das Mitglied flags der AccessibilityServiceInfo-Instanz des Dienstes auf FLAG_REQUEST_TOUCH_EXPLORATION_MODE, 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 Tippen & Entdecken anfordert, muss der Nutzer die Aktivierung der Funktion zulassen, falls sie noch nicht aktiv ist. Wenn diese Funktion aktiv ist, erhält der Dienst über die Callback-Methode onGesture() des Dienstes Benachrichtigungen über Touch-Gesten für Bedienungshilfen und kann im Namen des Nutzers reagieren.

Fortlaufende Touch-Gesten

Geräte mit Android 8.0 (API-Level 26) unterstützen fortlaufende Touch-Gesten oder programmatische Gesten, die mehr als ein Path-Objekt enthalten.

Wenn Sie eine Abfolge von Strichen angeben, können Sie festlegen, dass sie zu derselben programmatischen Geste gehören. Verwenden Sie dazu das letzte Argument willContinue im Konstruktor GestureDescription.StrokeDescription, 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 der Session What's new in Android Accessibility von der Google I/O 2017 ab 15:47 Uhr.

Aktionen für Bedienungshilfen verwenden

Bedienungshilfen können im Namen von Nutzern die Interaktion mit Apps vereinfachen und produktiver sein. Bedienungshilfen wurden 2011 hinzugefügt und 2012 deutlich ausgeweitet.

Wenn Sie im Namen von Nutzern handeln möchten, muss sich die Bedienungshilfe registrieren, um Ereignisse von Apps zu erhalten und die Berechtigung zum Ansehen von App-Inhalten anzufordern. Dazu setzen Sie android:canRetrieveWindowContent in der Dienstkonfigurationsdatei auf true. Wenn Ihr Dienst Ereignisse empfängt, kann er das Objekt AccessibilityNodeInfo aus dem Ereignis mit getSource() abrufen. Mit dem AccessibilityNodeInfo-Objekt kann der Dienst dann die Ansichtshierarchie untersuchen, um zu bestimmen, welche Aktion ausgeführt werden soll, und dann performAction() für den Nutzer verwenden.

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 der Dienst Aktionen innerhalb einer App ausführen. Wenn Ihr Dienst eine globale Aktion ausführen muss, z. B. den Startbildschirm aufrufen, auf die Schaltfläche „Zurück“ tippen oder den Benachrichtigungsbildschirm oder die Liste mit den zuletzt verwendeten Apps öffnen, verwenden Sie die Methode performGlobalAction().

Fokustypen verwenden

2012 wurde der Schwerpunkt von Android auf die Benutzeroberfläche Barrierefreiheit im Internet eingeführt. Bedienungshilfen können diesen Fokus verwenden, um beliebige sichtbare Elemente der Benutzeroberfläche auszuwählen und darauf zu reagieren. Dieser Fokustyp unterscheidet sich vom Eingabefokus, der festlegt, welches Bildschirmelement der Benutzeroberfläche eine Eingabe erhält, 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 einen Eingabefokus hat, während ein anderes Element auf Barrierefreiheit ausgerichtet ist. Der Zweck der Barrierefreiheit besteht darin, Bedienungshilfen eine Methode zur Interaktion mit sichtbaren Elementen auf einem Bildschirm bereitzustellen, unabhängig davon, ob das Element aus Systemperspektive eingabefokussierbar ist. Damit die Bedienungshilfe korrekt mit den Eingabeelementen einer App interagiert, folgen Sie den Richtlinien zum Testen der Barrierefreiheit einer App, um den Dienst in einer typischen App zu testen.

Eine Bedienungshilfe kann mithilfe der Methode AccessibilityNodeInfo.findFocus() bestimmen, welches Element der Benutzeroberfläche den Eingabefokus oder Barrierefreiheitsfokus hat. Mit der Methode focusSearch() können Sie auch nach Elementen suchen, die mit Eingabefokus ausgewählt werden können. Schließlich kann der Bedienungshilfendienst den Fokus auf die Barrierefreiheit mit der Methode performAction(AccessibilityNodeInfo.ACTION_SET_ACCESSIBILITY_FOCUS) festlegen.

Informationen sammeln

Bedienungshilfen verwenden Standardmethoden zum Erfassen und Darstellen von Schlüsseleinheiten für von Nutzern bereitgestellte Informationen wie Ereignisdetails, Text und Zahlen.

Details zu Fensteränderungen abrufen

Mit Android 9 (API-Level 28) und höher können Apps Fensteraktualisierungen erfassen, wenn eine App mehrere Fenster gleichzeitig neu erstellt. Wenn ein TYPE_WINDOWS_CHANGED-Ereignis eintritt, verwende die getWindowChanges() API, um festzustellen, wie sich die Fenster ändern. Während einer Aktualisierung mit mehreren Fenstern generiert jedes Fenster eine eigene Reihe von Ereignissen. Die Methode getSource() gibt die Stammansicht des Fensters zurück, das jedem Ereignis zugeordnet ist.

Wenn eine App Titel für den Bedienungshilfenbereich für ihre View-Objekte definiert, kann der Dienst erkennen, wenn die UI 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 hat oder ein Bereich verschwindet.

Termindetails abrufen

Android stellt Bedienungshilfen mithilfe von AccessibilityEvent-Objekten Informationen zur Interaktion mit der Benutzeroberfläche zur Verfügung. In früheren Android-Versionen boten die in einem Ereignis zur Barrierefreiheit verfügbaren Informationen nur begrenzte Kontextinformationen, obwohl sie viele Details zur von den Nutzern ausgewählten Benutzeroberflächensteuerung enthielten. In vielen Fällen können diese fehlenden Kontextinformationen entscheidend sein, um die Bedeutung des ausgewählten Steuerelements zu verstehen.

Ein Beispiel für eine Schnittstelle, bei der der Kontext von entscheidender Bedeutung ist, ist ein Kalender oder ein Tagesplaner. Wenn der Nutzer in einer Liste mit einem Montag bis Freitag ein Zeitfenster von 16:00 Uhr auswählt und die Bedienungshilfe „16:00 Uhr“ ankündigt, den Wochentag, den Tag des Monats oder den Monatsnamen jedoch nicht ankündigt, ist das resultierende Feedback verwirrend. In diesem Fall ist der Kontext einer UI-Steuerung für einen Nutzer, der eine Besprechung planen möchte, von entscheidender Bedeutung.

Seit 2011 erweitert Android die Menge an Informationen, die ein Bedienungshilfendienst zu einer Interaktion auf der Benutzeroberfläche erhalten kann, indem Barrierefreiheitsereignisse basierend auf der Ansichtshierarchie zusammengestellt werden. Eine Ansichtshierarchie besteht aus Komponenten der Benutzeroberfläche, die die Komponente (ihre übergeordneten Elemente) und die Elemente der Benutzeroberfläche enthalten, die in der jeweiligen Komponente enthalten sein können (ihre untergeordneten Elemente). Auf diese Weise kann Android mehr Details zu Ereignissen für Bedienungshilfen liefern, sodass Bedienungshilfen nützliches Feedback für Nutzer geben können.

Eine Bedienungshilfe ruft Informationen zu einem Ereignis auf der Benutzeroberfläche über ein AccessibilityEvent ab, das vom System an die Callback-Methode onAccessibilityEvent() des Dienstes übergeben wird. Dieses Objekt liefert Details zum Ereignis, einschließlich des Objekttyps, auf den reagiert wird, der Beschreibung des Objekts und andere Details.

  • AccessibilityEvent.getRecordCount() und getRecord(int): Mit diesen Methoden können Sie die Gruppe von AccessibilityRecord-Objekten abrufen, die zu den vom System übergebenen AccessibilityEvent beitragen. Diese Detailebene bietet mehr Kontext für das Ereignis, das die Bedienungshilfe auslöst.

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

Die Android-Plattform bietet die Möglichkeit, mit einem AccessibilityService die Ansichtshierarchie abzufragen. Dabei werden Informationen zu der UI-Komponente, die ein Ereignis generiert, sowie zu dessen übergeordneten und untergeordneten Elementen erfasst. Dazu legen Sie die folgende Zeile in Ihrer XML-Konfiguration fest:

android:canRetrieveWindowContent="true"

Anschließend können Sie mit getSource() ein AccessibilityNodeInfo-Objekt abrufen. Bei diesem Aufruf wird ein Objekt nur zurückgegeben, wenn das Fenster, von dem das Ereignis stammt, noch das aktive Fenster ist. Andernfalls wird null zurückgegeben, verhalten Sie sich also entsprechend.

Im folgenden Beispiel bewirkt der Code Folgendes, wenn ein Ereignis empfangen wird:

  1. Sofort das übergeordnete Element der Ansicht erfassen, von der das Ereignis stammt.
  2. In dieser Ansicht wird nach einem Label und einem Kästchen als untergeordnete Ansichten gesucht.
  3. Wenn sie gefunden werden, wird ein String erstellt, der an den Nutzer gemeldet werden soll. Dieser gibt das Label an und gibt an, ob es überprüft wurde.

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

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);
}

Jetzt haben Sie einen vollständigen, funktionierenden Bedienungshilfedienst. Konfigurieren Sie die Interaktion mit dem Nutzer, indem Sie das Sprachausgabe-Modul von Android hinzufügen oder ein Vibrator für haptisches Feedback verwenden.

Text verarbeiten

Geräte mit Android 8.0 (API-Level 26) und höher enthalten mehrere Textverarbeitungsfunktionen, mit denen Bedienungshilfen bestimmte Texteinheiten, die auf dem Bildschirm angezeigt werden, leichter erkennen und bearbeiten können.

Kurzinfos

Android 9 (API-Level 28) bietet verschiedene Funktionen, mit denen du Zugriff auf Kurzinfos in der Benutzeroberfläche einer App erhältst. 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 für die Interaktion mit dem Hinweistext eines textbasierten Objekts:

  • Mit den Methoden isShowingHintText() und setShowingHintText() wird angegeben und festgelegt, ob der aktuelle Textinhalt des Knotens den Hinweistext des Knotens darstellt.
  • getHintText() bietet Zugriff auf den Hinweistext selbst. Auch wenn ein Objekt keinen Hinweistext anzeigt, ist der Aufruf von getHintText() erfolgreich.

Position von Bildschirmtextzeichen

Auf Geräten mit Android 8.0 (API-Level 26) und höher können Bedienungshilfen die Bildschirmkoordinaten für die Begrenzungsrahmen jedes sichtbaren Zeichens in einem TextView-Widget ermitteln. Dienste ermitteln diese Koordinaten, indem sie refreshWithExtraData() aufrufen und dabei EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY als erstes Argument und ein Bundle-Objekt als zweites Argument übergeben. Bei Ausführung der Methode füllt das System das Argument Bundle mit einem Parcelable-Array von Rect-Objekten auf. 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. Beachten Sie beim Erstellen eines Bereichs mit RangeInfo.obtain() oder beim Abrufen der Extremwerte mit getMin() und getMax(), dass Geräte mit Android 8.0 (API-Level 26) und höher einseitige Bereiche standardisiert darstellen:

Auf Ereignisse zur Barrierefreiheit reagieren

Ihr Dienst ist nun so eingerichtet, dass er ausgeführt wird und auf Ereignisse wartet. Schreiben Sie nun Code, damit er weiß, was zu tun ist, wenn ein AccessibilityEvent eintrifft. Überschreiben Sie zuerst die Methode onAccessibilityEvent(AccessibilityEvent). Verwenden Sie dabei 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);
    ...
}

Weitere Informationen

Weitere Informationen finden Sie in den folgenden Ressourcen:

Leitfäden

Codelabs