Eigene Bedienungshilfe erstellen

Eine Bedienungshilfe ist eine App, die die Benutzeroberfläche verbessert, um Nutzer mit Behinderungen oder Personen, 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 kleines Kind kümmern oder an einer sehr lauten Party teilnehmen, möglicherweise zusätzliches oder alternatives Feedback zur Benutzeroberfläche benötigen.

Android bietet standardmäßige Bedienungshilfen, einschließlich TalkBack, und Entwickler können ihre eigenen Dienste erstellen und vertreiben. In diesem Dokument werden die Grundlagen der Erstellung 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 du ein neues Projekt für diese Service erstellst und nicht beabsichtigst, eine App damit verknüpft zu haben, kannst du die Starter-Activity-Klasse aus der Quelle entfernen.

Manifestdeklarationen und Berechtigungen

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

Erklärung zu Bedienungshilfen

Damit deine App als Bedienungshilfe behandelt werden kann, musst du in deinem Manifest in das application-Element ein service-Element anstelle des activity-Elements einfügen. Fügen Sie außerdem im Element service einen Intent-Filter für Bedienungshilfen ein. Außerdem muss das Manifest den Dienst durch Hinzufügen der Berechtigung BIND_ACCESSIBILITY_SERVICE schützen, 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 der Bedienungshilfen

Bedienungshilfen müssen eine Konfiguration bereitstellen, in der die Arten von Bedienungshilfen-Ereignissen angegeben sind, die der Dienst verarbeitet, sowie zusätzliche Informationen zum Dienst. Die Konfiguration eines Bedienungshilfendiensts ist in der Klasse AccessibilityServiceInfo enthalten. Der Dienst kann mithilfe einer Instanz dieser Klasse und setServiceInfo() zur Laufzeit eine Konfiguration erstellen und festlegen. Bei dieser Methode sind jedoch nicht alle Konfigurationsoptionen verfügbar.

Du kannst deinem Manifest ein <meta-data>-Element mit einem Verweis auf eine Konfigurationsdatei hinzufügen. So kannst du die gesamte Palette der Optionen für die 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 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 Barrierefreiheitsdienstes 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 beim Festlegen der Konfigurationsvariablen für Ihre Bedienungshilfe Folgendes, damit das System weiß, wie und wann es ausgeführt werden soll:

  • Auf welche Ereignistypen soll die Funktion reagieren?
  • Muss der Dienst für alle Anwendungen oder nur für bestimmte Paketnamen aktiv sein?
  • Welche verschiedenen Feedbacktypen 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. Dazu überschreiben Sie die Methode onServiceConnected() und konfigurieren dort Ihren Dienst, 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 so aus, wenn sie mit XML definiert wurden:

<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 Ihrer 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

Ein Bedienungshilfendienst muss die AccessibilityService-Klasse erweitern und die folgenden Methoden aus dieser Klasse überschreiben. Diese Methoden werden in der Reihenfolge dargestellt, in der sie vom Android-System aufgerufen werden: vom Start des Dienstes (onServiceConnected()) über die Ausführung (onAccessibilityEvent(), onInterrupt()) bis zum Herunterfahren (onUnbind()).

  • onServiceConnected() (optional): Diese Methode wird vom System aufgerufen, wenn eine Verbindung zu Ihrer Bedienungshilfe hergestellt wird. Verwenden Sie diese Methode für einmalige Einrichtungsschritte für Ihren Dienst, einschließlich der Verbindung zu Diensten für Nutzerfeedbacksysteme wie dem Audiomanager oder dem 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 AccessibilityEvent erkannt wird, die den von Ihrer Bedienungshilfe angegebenen Ereignisfilterparametern entspricht, z. B. wenn der Nutzer auf eine Schaltfläche tippt oder sich auf ein UI-Steuerelement in einer App konzentriert, zu der Ihre Bedienungshilfe Feedback gibt. Wenn das System diese Methode aufruft, übergibt es die zugehörige AccessibilityEvent, die 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 von Ihrem Dienst bereitgestellte Feedback unterbrochen werden möchte. Dies geschieht normalerweise als Reaktion auf eine Nutzeraktion, z. B. wenn der Fokus auf ein anderes Steuerelement verschoben wird. Diese Methode kann während des Lebenszyklus Ihres Dienstes mehrmals aufgerufen werden.

  • onUnbind() (optional): Diese Methode wird vom System aufgerufen, wenn die Bedienungshilfe heruntergefahren wird. Verwenden Sie diese Methode, um ein einmaliges Herunterfahren durchzuführen. Dazu gehört auch die Aufhebung der Zuweisung von Diensten für Nutzerfeedbacksysteme wie Audiomanager oder Gerätevibrator.

Diese Callback-Methoden bieten die Grundstruktur für die Bedienungshilfe. Sie können entscheiden, wie Daten verarbeitet werden, die vom Android-System in Form von AccessibilityEvent-Objekten bereitgestellt werden, und dem Nutzer Feedback geben. Weitere Informationen zum Abrufen von Informationen aus einem Bedienungshilfen-Ereignis finden Sie unter Ereignisdetails abrufen.

Für Veranstaltungen zur Barrierefreiheit registrieren

Eine der wichtigsten Funktionen der Konfigurationsparameter des Bedienungshilfendiensts besteht darin, anzugeben, welche Arten von Bedienungshilfenereignissen Ihr Dienst verarbeiten kann. Wenn Sie diese Informationen angeben, können Bedienungshilfen miteinander zusammenarbeiten. Außerdem haben Sie die Möglichkeit, nur bestimmte Ereignistypen aus bestimmten Anwendungen zu verarbeiten. Die Ereignisfilterung kann die folgenden Kriterien umfassen:

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

  • Ereignistypen:Geben Sie die Arten von Bedienungshilfenereignissen an, die Ihr Dienst verarbeiten soll. Sie können diesen Parameter in den Konfigurationsdateien des Bedienungshilfendienstes mit dem Attribut android:accessibilityEventTypes als durch das Zeichen | getrennte Liste festlegen, z. B. accessibilityEventTypes="typeViewClicked|typeViewFocused". Alternativ können Sie sie mit dem Mitglied AccessibilityServiceInfo.eventTypes festlegen.

Überlegen Sie sich beim Einrichten der Bedienungshilfe sorgfältig, welche Ereignisse er verarbeiten kann, und registrieren Sie sich nur für diese Ereignisse. Da Nutzer mehrere Bedienungshilfen gleichzeitig aktivieren können, darf Ihr Dienst keine Ereignisse verarbeiten, die er nicht verarbeiten kann. Denken Sie daran, dass andere Dienste diese Ereignisse verarbeiten können, um die Nutzererfahrung 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 können Sie die Lautstärke der Audioausgabe Ihrer Bedienungshilfe unabhängig von anderen Tönen auf dem Gerät steuern.

Bedienungshilfen können diesen Streamtyp verwenden, indem sie die Option FLAG_ENABLE_ACCESSIBILITY_VOLUME festlegen. Anschließend kannst du die Audiolautstärke des Geräts für Bedienungshilfen ändern, indem du auf der Geräteinstanz von AudioManager die Methode adjustStreamVolume() aufrufst.

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 zu den Neuerungen bei der Android-Barrierefreiheit im Internet von der Google I/O 2017, das um 6:35 Uhr startet.

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. Obwohl durch diese Tastenkombination standardmäßig TalkBack aktiviert und deaktiviert wird, können Nutzer die Schaltfläche so konfigurieren, dass alle auf ihrem Gerät installierten Dienste aktiviert und deaktiviert werden.

Damit Nutzer über den Kurzbefehl für Bedienungshilfen auf einen bestimmten Bedienungshilfe-Dienst zugreifen können, muss der Dienst das Feature zur Laufzeit anfordern.

Weitere Informationen finden Sie im Video zu den Neuerungen bei der Android-Barrierefreiheit im Internet von der Google I/O 2017, das um 13:25 Uhr startet.

Schaltfläche „Bedienungshilfen“

Auf Geräten mit einem von Software gerenderten Navigationsbereich und Android 8.0 (API-Level 26) oder höher befindet sich auf der rechten Seite der Navigationsleiste die Schaltfläche „Bedienungshilfen“. Wenn Nutzer auf diese Schaltfläche klicken, können sie abhängig vom aktuell auf dem Bildschirm angezeigten Inhalt eine von mehreren aktivierten Bedienungshilfen und -diensten aufrufen.

Damit Nutzer einen bestimmten Bedienungshilfendienst über die Schaltfläche „Bedienungshilfen“ aufrufen können, muss der Dienst das Flag FLAG_REQUEST_ACCESSIBILITY_BUTTON im android:accessibilityFlags-Attribut eines AccessibilityServiceInfo-Objekts hinzufügen. Der Dienst kann dann Callbacks mit registerAccessibilityButtonCallback() registrieren.

Im folgenden Code-Snippet sehen Sie, wie Sie einen Bedienungshilfedienst so konfigurieren können, dass er auf das Drücken der Schaltfläche für Bedienungshilfen 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 zu den Neuerungen bei der Android-Barrierefreiheit im Internet von der Google I/O 2017, das um 16:28 Uhr gestartet wurde.

Gesten auf dem Fin­gerabdrucksensor

Bedienungshilfen auf Geräten mit Android 8.0 (API-Level 26) oder höher können auf Wischen (nach oben, unten, links und rechts) entlang des Fingerabdrucksensors eines Geräts reagieren. Führen Sie die folgende Sequenz 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 Callbacks.

Denken Sie daran, dass nicht alle Geräte einen Fingerabdrucksensor haben. Mit der Methode isHardwareDetected() können Sie feststellen, ob ein Gerät den Sensor unterstützt. Auch auf einem Gerät mit Fingerabdrucksensor kann Ihr Dienst den Sensor nicht verwenden, wenn er zur Authentifizierung genutzt wird. Wenn Sie herausfinden 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 Fingerabdruck-Gesten zum Navigieren 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 zu den Neuerungen bei der Android-Barrierefreiheit im Internet von der Google I/O 2017, das um 9:03 Uhr beginnt.

Mehrsprachige Sprachausgabe

Ab Android 8.0 (API-Level 26) kann der Text-in-Sprache-Dienst (TTS) von Android Wortgruppen in mehreren Sprachen innerhalb eines einzigen Textblocks erkennen und sprechen. Um diesen automatischen Sprachwechsel in einer Bedienungshilfe zu ermöglichen, verpacken Sie alle Strings in LocaleSpan-Objekte, 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 zu den Neuerungen bei der Android-Barrierefreiheit im Internet von der Google I/O 2017, das um 10:59 Uhr startet.

Im Namen von Nutzern handeln

Ab 2011 können Bedienungshilfen im Namen von Nutzern agieren, unter anderem den Eingabefokus ändern und Elemente der Benutzeroberfläche auswählen (aktivieren). Im Jahr 2012 wurde der Bereich der Aktionen um Scrolllisten und die Interaktion mit Textfeldern erweitert. Bedienungshilfen können auch globale Aktionen ausführen, z. B. zum Startbildschirm gehen, die Schaltfläche „Zurück“ drücken und den Benachrichtigungsbildschirm und die Liste der zuletzt verwendeten Apps öffnen. Seit 2012 umfasst Android den Schwerpunkt auf Bedienungshilfen, d. h., alle sichtbaren Elemente können von Bedienungshilfen ausgewählt werden.

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

Auf Gesten achten

Bedienungshilfen können bestimmte Gesten erkennen und im Auftrag eines Nutzers reagieren. Für diese Funktion muss Ihre Bedienungshilfe die Aktivierung der Funktion „Tippen & Entdecken“ anfordern. Ihr Dienst kann diese Aktivierung anfordern, indem er das Mitglied flags 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 Tippen & Entdecken angefordert hat, muss der Nutzer die Aktivierung der Funktion zulassen, falls sie nicht bereits aktiv ist. Wenn diese Funktion aktiviert 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 Touch-Gesten mit mehr als einem Path-Objekt.

Beim Angeben einer Abfolge von Strichen können Sie angeben, dass sie zu derselben programmatischen Geste gehören. Dazu verwenden Sie das abschließende 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 zu den Neuerungen bei der Android-Barrierefreiheit im Internet von der Google I/O 2017, das um 15:47 Uhr startet.

Aktionen für Bedienungshilfen verwenden

Bedienungshilfen können im Namen der Nutzer agieren, um Interaktionen mit Apps zu vereinfachen und produktiver zu sein. Die Bedienungshilfen für Aktionen wurden 2011 hinzugefügt und 2012 erheblich erweitert.

Wenn Sie im Namen von Nutzern handeln möchten, muss Ihre Bedienungshilfe registrieren, damit Ereignisse von Apps empfangen werden können. Außerdem muss die Berechtigung zum Ansehen der App-Inhalte angefordert werden. Dazu setzen Sie android:canRetrieveWindowContent in der Dienstkonfigurationsdatei auf true. Wenn der Dienst Ereignisse empfängt, kann er mit getSource() das Objekt AccessibilityNodeInfo aus dem Ereignis abrufen. Mit dem AccessibilityNodeInfo-Objekt kann Ihr Dienst dann die Ansichtshierarchie untersuchen, um zu bestimmen, 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 innerhalb einer App ausführen. Wenn Ihr Dienst eine globale Aktion ausführen muss, z. B. zum Startbildschirm, auf die Schaltfläche „Zurück“ tippen oder den Benachrichtigungsbildschirm oder die Liste der zuletzt verwendeten Apps öffnen muss, verwenden Sie die Methode performGlobalAction().

Fokustypen verwenden

2012 wurde bei Android der Fokus auf der Benutzeroberfläche mit dem Namen Schwerpunkt auf Barrierefreiheit 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, mit dem festgelegt wird, welches Benutzeroberflächenelement auf dem Bildschirm eine Eingabe empfängt, wenn ein Nutzer Zeichen eingibt, die Eingabetaste auf der 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 auf die Barrierefreiheit hat. Der Zweck des Fokus auf Bedienungshilfen besteht darin, Bedienungshilfen eine Methode zur Interaktion mit sichtbaren Elementen auf einem Bildschirm zu bieten, unabhängig davon, ob das Element aus Systemperspektive eingabefokussierbar ist. Damit deine Bedienungshilfe korrekt mit den Eingabeelementen der App interagiert, folge den Richtlinien zum Testen der Barrierefreiheit einer App. So kannst du deinen Dienst testen, während du eine typische App verwendest.

Eine Bedienungshilfe kann mithilfe der Methode AccessibilityNodeInfo.findFocus() bestimmen, welches Benutzeroberflächenelement den Eingabe- oder Bedienungshilfenfokus hat. Sie können auch nach Elementen suchen, die mit dem Eingabefokus ausgewählt werden können. Verwenden Sie dazu die Methode focusSearch(). Schließlich kann der Bedienungshilfenfokus mithilfe der Methode performAction(AccessibilityNodeInfo.ACTION_SET_ACCESSIBILITY_FOCUS) festgelegt werden.

Informationen sammeln

Bedienungshilfen haben Standardmethoden, um Schlüsseleinheiten der von Nutzern bereitgestellten Informationen wie Ereignisdetails, Text und Zahlen zu erfassen und darzustellen.

Details zu Fensteränderungen abrufen

Mit Android 9 (API-Level 28) und höher können Apps Fensterupdates verfolgen, wenn eine App mehrere Fenster gleichzeitig neu zieht. Wenn ein TYPE_WINDOWS_CHANGED-Ereignis eintritt, können Sie mit der getWindowChanges() API bestimmen, wie sich die Fenster ändern. Während einer Aktualisierung im Mehrfenstermodus erzeugt jedes Fenster seine eigenen Ereignisse. Die Methode getSource() gibt die Stammansicht des Fensters zurück, das mit jedem Ereignis verknüpft ist.

Wenn eine App Titel des Bereichs für Bedienungshilfen 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. Beispielsweise kann das Framework erkennen, wenn ein Bereich einen neuen Titel hat oder wenn ein Bereich ausgeblendet wird.

Termindetails abrufen

Android stellt Bedienungshilfen Informationen zur Interaktion der Benutzeroberfläche über AccessibilityEvent-Objekte bereit. In früheren Android-Versionen boten die in einem Bedienungshilfen-Ereignis verfügbaren Informationen und wichtige Details zur Steuerung der Benutzeroberfläche, die von Nutzern ausgewählt wurden, begrenzte Kontextinformationen. In vielen Fällen können diese fehlenden Kontextinformationen entscheidend sein, um die Bedeutung der ausgewählten Einstellung zu verstehen.

Ein Beispiel für eine Schnittstelle, bei der der Kontext entscheidend ist, ist ein Kalender oder Tagesplaner. Wenn der Nutzer in einer Liste von Montag bis Freitag ein Zeitfenster von 16:00 Uhr auswählt und die Bedienungshilfe „16 Uhr“ ansagt, aber weder den Wochentag- noch den Tag des Monats oder den Monat angibt, ist das daraus resultierende Feedback verwirrend. In diesem Fall ist der Kontext einer Steuerung auf 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 Bedienungshilfedienst zu einer Interaktion auf der Benutzeroberfläche erhalten kann, indem Bedienungshilfen basierend auf der Ansichtshierarchie erstellt werden. Eine Ansichtshierarchie besteht aus einer Gruppe von Benutzeroberflächenkomponenten, die die Komponente (ihre übergeordneten Elemente) enthalten, sowie den Benutzeroberflächenelementen, die diese Komponente (untergeordnete Elemente) enthalten könnte. Auf diese Weise kann Android umfassendere Details zu Bedienungshilfen-Ereignissen bereitstellen, sodass Bedienungshilfen den Nutzern nützlicheres Feedback geben.

Eine Bedienungshilfe ruft Informationen zu einem Benutzeroberflächenereignis ü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 Typs des Objekts, auf das reagiert wird, des Beschreibungstexts und weiterer Details.

  • AccessibilityEvent.getRecordCount() und getRecord(int): Mit diesen Methoden können Sie eine Gruppe von AccessibilityRecord-Objekten abrufen, die zu dem vom System übergebenen AccessibilityEvent-Objekt 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 Ansichts-Layout-Hierarchie (über- und untergeordnete Elemente) der Komponente anfordern, von der das Bedienungshilfen-Ereignis stammt. Mit dieser Funktion kann eine Bedienungshilfe den vollständigen Kontext eines Ereignisses untersuchen, einschließlich des Inhalts und Status der zugehörigen Ansichten oder untergeordneten Ansichten.

Auf der Android-Plattform kann ein AccessibilityService die Ansichtshierarchie abfragen und Daten zur UI-Komponente, die ein Ereignis generiert, sowie zu den übergeordneten und untergeordneten Elementen erfassen. Legen Sie dazu die folgende Zeile in Ihrer XML-Konfiguration fest:

android:canRetrieveWindowContent="true"

Anschließend rufen Sie mit getSource() ein AccessibilityNodeInfo-Objekt ab. Bei diesem Aufruf wird nur dann ein Objekt zurückgegeben, wenn das Fenster, aus dem das Ereignis stammt, noch immer das aktive Fenster ist. Wenn nicht, wird null zurückgegeben. Gehen Sie also entsprechend vor.

Im folgenden Beispiel führt der Code folgende Schritte aus, wenn ein Ereignis empfangen wird:

  1. Greift sofort auf das übergeordnete Element der Ansicht zu, aus der das Ereignis stammt.
  2. In dieser Ansicht wird als untergeordnete Ansicht nach einem Label und einem Kästchen gesucht.
  3. Wenn sie gefunden werden, wird ein String für den Bericht an den Nutzer erstellt, der das Label angibt und angibt, ob es geprüft wurde.

Wenn beim Durchlaufen der Ansichtshierarchie an irgendeinem Punkt 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 eine vollständige, funktionierende Bedienungshilfe. Konfiguriere die Interaktionen mit dem Nutzer. Füge dazu das Sprachausgabe-Engine von Android hinzu oder verwende Vibrator für haptisches Feedback.

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

Mit Android 9 (API-Level 28) werden mehrere Funktionen eingeführt, mit denen Sie auf 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 zur Interaktion mit dem Hinweistext eines textbasierten Objekts:

  • Die Methoden isShowingHintText() und setShowingHintText() geben bzw. legen fest, 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.

Positionen von Bildschirmtextzeichen

Auf Geräten mit Android 8.0 (API-Level 26) und höher können Bedienungshilfen die Bildschirmkoordinaten für den Begrenzungsrahmen jedes sichtbaren Zeichens in einem TextView-Widget bestimmen. Dienste finden diese Koordinaten, indem sie refreshWithExtraData() aufrufen und EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY als erstes Argument und ein Bundle-Objekt als zweites Argument übergeben. Bei der Ausführung der Methode füllt das System das Argument Bundle mit einem aggregierbaren 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 auf standardisierte Weise darstellen:

Auf Bedienungshilfen reagieren

Nachdem Ihr Dienst nun ausgeführt und auf Ereignisse überwacht wird, sollten Sie Code schreiben, damit er weiß, was zu tun ist, wenn ein AccessibilityEvent eintrifft. Ü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, durch die das Ereignis ausgelöst wird:

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