1. Einführung
Bedienungshilfen sind eine Funktion des Android-Frameworks, die entwickelt wurde, um Nutzern im Namen von auf Android-Geräten installierten Anwendungen alternatives Navigationsfeedback zu geben. Ein Bedienungshilfendienst kann im Namen der Anwendung mit dem Nutzer kommunizieren, z. B. indem er Text in Sprache umwandelt oder haptisches Feedback gibt, wenn ein Nutzer den Mauszeiger auf einen wichtigen Bereich des Bildschirms bewegt. In diesem Codelab erfahren Sie, wie Sie einen sehr einfachen Barrierefreiheitsdienst erstellen.
Was ist ein Bedienungshilfendienst?
Ein Dienst für Barrierefreiheit unterstützt Nutzer mit Beeinträchtigungen bei der Verwendung von Android-Geräten und ‑Apps. Es handelt sich um einen privilegierten Dienst, der im Hintergrund ausgeführt wird und Nutzern hilft, Informationen auf dem Bildschirm zu verarbeiten und sinnvoll mit einem Gerät zu interagieren.
Beispiele für häufig verwendete Bedienungshilfen
- Schalterzugriff: Mit dieser Funktion können Android-Nutzer mit eingeschränkter Mobilität Geräte über einen oder mehrere Schalter bedienen.
- Voice Access (Beta): Mit dieser Funktion können Android-Nutzer mit eingeschränkter Mobilität ein Gerät über Sprachbefehle steuern.
- TalkBack: Ein Screenreader, der häufig von sehbehinderten oder blinden Nutzern verwendet wird.
Dienst für Barrierefreiheit erstellen
Google bietet zwar Dienste wie den Schalterzugriff, Voice Access und TalkBack für Android-Nutzer an, diese Dienste können jedoch nicht alle Nutzer mit Behinderungen unterstützen. Da viele Nutzer mit Behinderungen spezielle Anforderungen haben, sind die Android-APIs zum Erstellen von Barrierefreiheitsdiensten offen. Entwickler können Barrierefreiheitsdienste erstellen und über den Play Store vertreiben.
Was Sie erstellen
In diesem Codelab entwickeln Sie einen einfachen Dienst, der mit der Accessibility API einige nützliche Dinge erledigt. Wenn Sie eine einfache Android-App schreiben können, können Sie auch einen ähnlichen Dienst entwickeln.
Die Accessibility API ist leistungsstark: Der Code für den Dienst, den Sie erstellen, ist in nur vier Dateien enthalten und umfasst etwa 200 Zeilen.
Der Endnutzer
Sie erstellen einen Dienst für einen hypothetischen Nutzer mit den folgenden Merkmalen:
- Der Nutzer hat Schwierigkeiten, die Seitentasten eines Geräts zu erreichen.
- Der Nutzer hat Schwierigkeiten beim Scrollen oder Wischen.
Dienstdetails
Ihr Dienst blendet eine globale Aktionsleiste auf dem Bildschirm ein. Der Nutzer kann auf die Schaltflächen in dieser Leiste tippen, um die folgenden Aktionen auszuführen:
- Schalte das Gerät aus, ohne die Ein/Aus-Taste an der Seite des Smartphones zu drücken.
- Sie können die Lautstärke anpassen, ohne die Lautstärketasten an der Seite des Smartphones zu berühren.
- Scrollvorgänge ausführen, ohne tatsächlich zu scrollen
- Führen Sie einen Wischvorgang aus, ohne eine Wischgeste verwenden zu müssen.
Voraussetzungen
In diesem Codelab wird davon ausgegangen, dass Sie Folgendes verwenden:
- Ein Computer mit Android Studio.
- Ein Terminal zum Ausführen einfacher Shell-Befehle.
- Ein Gerät mit Android 7.0 (Nougat), das mit dem Computer verbunden ist, den Sie für die Entwicklung verwenden.
Los geht's!
2. Einrichtung
Erstellen Sie über das Terminal ein Verzeichnis, in dem Sie arbeiten werden. Wechseln Sie in dieses Verzeichnis.
Code herunterladen
Sie können das Repository mit dem Code für dieses Codelab klonen:
git clone https://github.com/android/codelab-android-accessibility.git
Das Repository enthält mehrere Android Studio-Projekte. Öffnen Sie GlobalActionBarService in Android Studio.
Starten Sie Android Studio, indem Sie auf das Studio-Symbol klicken:

Wählen Sie die Option Import project (Eclipse ADT, Gradle, etc.) aus:

Rufen Sie den Speicherort auf, an dem Sie die Quelle geklont haben, und wählen Sie GlobalActionBarService aus.
Wechseln Sie dann über ein Terminal in das Stammverzeichnis.
3. Ausgangscode verstehen
Sehen Sie sich das geöffnete Projekt an.
Das Grundgerüst für den Barrierefreiheitsdienst wurde bereits für Sie erstellt. Der gesamte Code, den Sie in diesem Codelab schreiben, ist auf die folgenden vier Dateien beschränkt:
- app/src/main/AndroidManifest.xml
- app/src/main/res/layout/action_bar.xml
- app/src/main/res/xml/global_action_bar_service.xml
- app/src/main/java/com/example/android/globalactionbarservice/GlobalActionBarService.java
Hier finden Sie eine Beschreibung des Inhalts der einzelnen Dateien.
AndroidManifest.xml
Informationen zur Bedienungshilfe werden im Manifest deklariert:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.globalactionbarservice">
<application>
<service
android:name=".GlobalActionBarService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:exported="true">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/global_action_bar_service" />
</service>
</application>
</manifest>
Die folgenden drei erforderlichen Elemente sind in AndroidManifest.xml deklariert:
- Berechtigung zum Binden an eine Bedienungshilfe:
<service
...
android:permission = "android.permission.BIND_ACCESSIBILITY_SERVICE">
...
</service>
- Der Intent AccessibilityService:
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
- Speicherort der Datei, die die Metadaten für den Dienst enthält, den Sie erstellen:
<meta-data
...
android:resource="@xml/global_action_bar_service" />
</service>
global_action_bar_service.xml
Diese Datei enthält die Metadaten für den Dienst.
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagDefault"
android:canPerformGestures="true"
android:canRetrieveWindowContent="true" />
Mit dem Element <accessibility-service> wurden die folgenden Metadaten definiert:
- Der Feedbacktyp für diesen Dienst. In diesem Codelab wird feedbackGeneric verwendet, was ein guter Standardwert ist.
- Die Bedienungshilfen-Flags für den Dienst (in diesem Codelab werden Standard-Flags verwendet).
- Die für den Dienst erforderlichen Funktionen:
- Damit Wischvorgänge ausgeführt werden können, ist android:canPerformGestures auf true gesetzt.
- Um Fensterinhalte abzurufen, wird android:canRetrieveWindowContent auf true gesetzt.
GlobalActionBarService.java
Der Großteil des Codes für den Barrierefreiheitsdienst befindet sich in GlobalActionBarService.java. Anfangs enthält die Datei den absolut erforderlichen Code für einen Bedienungshilfendienst:
- Eine Klasse, die AccessibilityService erweitert.
- Einige erforderliche überschriebene Methoden, die in diesem Codelab leer gelassen wurden.
public class GlobalActionBarService extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
}
@Override
public void onInterrupt() {
}
}
Im Laufe des Codelabs fügen Sie dieser Datei Code hinzu.
action_bar.xml
Der Dienst stellt eine Benutzeroberfläche mit vier Schaltflächen bereit. Die Layoutdatei action_bar.xml enthält das Markup zum Anzeigen dieser Schaltflächen:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
Diese Datei enthält derzeit ein leeres LinearLayout. Im Codelab fügen Sie Markup für die Schaltflächen hinzu.
Anwendung starten
Vergewissern Sie sich, dass ein Gerät mit Ihrem Computer verbunden ist. Klicken Sie in der Menüleiste oben auf dem Bildschirm auf das grüne Play-Symbol
. Dadurch sollte die App gestartet werden, an der Sie gerade arbeiten.
Gehen Sie zu den Einstellungen > Bedienungshilfen. Der Global Action Bar Service ist auf Ihrem Gerät installiert.

Klicken Sie auf Global Action Bar Service und aktivieren Sie den Dienst. Das folgende Dialogfeld mit Berechtigungen wird angezeigt:

Der Bedienungshilfendienst fordert die Berechtigung an, Nutzeraktionen zu beobachten, Fensterinhalte abzurufen und im Namen des Nutzers Gesten auszuführen. Wenn Sie einen Drittanbieterdienst für Barrierefreiheit verwenden, achten Sie darauf, dass Sie der Quelle wirklich vertrauen.
Das Ausführen des Dienstes hat noch keine Auswirkungen, da wir noch keine Funktionen hinzugefügt haben. Fangen wir damit an.
4. Schaltflächen erstellen
Öffnen Sie action_bar.xml in res/layout. Fügen Sie das Markup in das derzeit leere LinearLayout ein:
<LinearLayout ...>
<Button
android:id="@+id/power"
android:text="@string/power"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/volume_up"
android:text="@string/volume"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/scroll"
android:text="@string/scroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/swipe"
android:text="@string/swipe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Dadurch werden Schaltflächen erstellt, die der Nutzer drücken kann, um Aktionen auf dem Gerät auszulösen.
Öffnen Sie GlobalActionBarService.java und fügen Sie eine Variable zum Speichern des Layouts für die Aktionsleiste hinzu:
public class GlobalActionBarService extends AccessibilityService {
FrameLayout mLayout;
...
}
Fügen Sie nun eine onServiceStarted()-Methode hinzu:
public class GlobalActionBarService extends AccessibilityService {
FrameLayout mLayout;
@Override
protected void onServiceConnected() {
// Create an overlay and display the action bar
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
mLayout = new FrameLayout(this);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
lp.format = PixelFormat.TRANSLUCENT;
lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.gravity = Gravity.TOP;
LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.action_bar, mLayout);
wm.addView(mLayout, lp);
}
}
Der Code erweitert das Layout und fügt die Aktionsleiste oben auf dem Bildschirm hinzu.
Die Methode onServiceConnected() wird ausgeführt, wenn der Dienst verbunden ist. Der Bedienungshilfen-Dienst hat jetzt alle Berechtigungen, die für seine Funktion erforderlich sind. Die wichtigste Berechtigung, die Sie hier verwenden, ist WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY. Mit dieser Berechtigung können Sie direkt auf dem Display über vorhandenen Inhalten zeichnen, ohne einen komplizierten Berechtigungsablauf durchlaufen zu müssen.
Lebenszyklus von Bedienungshilfen
Der Lebenszyklus eines Barrierefreiheitsdienstes wird ausschließlich vom System verwaltet und folgt dem etablierten Dienstlebenszyklus.
- Ein Barrierefreiheitsdienst wird gestartet, wenn der Nutzer ihn explizit in den Geräteeinstellungen aktiviert.
- Nachdem das System an einen Dienst gebunden wurde, wird onServiceConnected() aufgerufen. Diese Methode kann von Diensten überschrieben werden, die nach dem Binden eine Einrichtung durchführen möchten.
- Ein Bedienungshilfendienst wird beendet, wenn der Nutzer ihn in den Geräteeinstellungen deaktiviert oder wenn er disableSelf() aufruft.
Dienst ausführen
Bevor Sie den Dienst mit Android Studio starten können, müssen Sie dafür sorgen, dass Ihre Ausführungseinstellungen richtig konfiguriert sind.
Bearbeiten Sie Ihre Ausführungskonfiguration (verwenden Sie „Ausführen“ im oberen Menü und gehen Sie zu „Konfigurationen bearbeiten“). Ändern Sie dann im Drop-down-Menü die Startoption von „Standardaktivität“ in „Nichts“.

Sie sollten den Dienst jetzt über Android Studio starten können.
Klicken Sie in der Menüleiste oben auf dem Bildschirm auf das grüne Play-Symbol
. Rufen Sie dann Einstellungen > Bedienungshilfen auf und aktivieren Sie Global Action Bar Service.
Auf dem Bildschirm sollten die vier Schaltflächen der Dienst-Benutzeroberfläche über dem angezeigten Inhalt zu sehen sein.

Jetzt fügen Sie den vier Schaltflächen Funktionen hinzu, damit ein Nutzer sie antippen kann, um nützliche Aktionen auszuführen.
5. Ein/Aus-Taste konfigurieren
Fügen Sie die Methode configurePowerButton() zu GlobalActionBarService.java hinzu:
private void configurePowerButton() {
Button powerButton = (Button) mLayout.findViewById(R.id.power);
powerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
performGlobalAction(GLOBAL_ACTION_POWER_DIALOG);
}
});
}
Für den Zugriff auf das Ein/Aus-Schaltflächenmenü verwendet configurePowerButton() die Methode performGlobalAction(), die von AccessibilityService bereitgestellt wird. Der Code, den Sie gerade hinzugefügt haben, ist einfach: Wenn der Nutzer auf die Schaltfläche klickt, wird ein onClickListener() ausgelöst. Dadurch wird performGlobalAction(GLOBAL_ACTION_POWER_DIALOG) aufgerufen und das Ein/Aus-Dialogfeld wird dem Nutzer angezeigt.
Globale Aktionen sind nicht mit Ansichten verknüpft. Das Drücken der Zurück-Taste, der Home-Taste oder der Taste für die letzten Apps sind weitere Beispiele für globale Aktionen.
Fügen Sie nun configurePowerButton() am Ende der Methode onServiceConnected() hinzu:
@Override
protected void onServiceConnected() {
...
configurePowerButton();
}
Klicken Sie in der Menüleiste oben auf dem Bildschirm auf das grüne Play-Symbol
. Rufen Sie dann die Einstellungen > Bedienungshilfen auf und starten Sie den Global Action Bar Service.
Drücken Sie die Ein/Aus-Taste, um das Ein/Aus-Dialogfeld aufzurufen.
6. Lautstärketaste konfigurieren
Fügen Sie die Methode configureVolumeButton() zu GlobalActionBarService.java hinzu:
private void configureVolumeButton() {
Button volumeUpButton = (Button) mLayout.findViewById(R.id.volume_up);
volumeUpButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
}
});
}
Die Methode configureVolumeButton() fügt einen onClickListener() hinzu, der ausgelöst wird, wenn der Nutzer die Lautstärketaste drückt. In diesem Listener verwendet configureVolumeButton() einen AudioManager, um die Streamlautstärke anzupassen.
Beachten Sie, dass jeder die Lautstärke steuern kann. Dazu ist kein Barrierefreiheitsdienst erforderlich.
Fügen Sie nun configureVolumeButton() am Ende der Methode onServiceConnected() hinzu:
@Override
protected void onServiceConnected() {
...
configureVolumeButton();
}
Klicken Sie in der Menüleiste oben auf dem Bildschirm auf das grüne Play-Symbol
. Rufen Sie dann die Einstellungen > Bedienungshilfen auf und starten Sie den Global Action Bar Service.
Drücken Sie die Lautstärketaste, um die Lautstärke zu ändern.
Der hypothetische Nutzer, der die Lautstärkeregler an der Seite des Geräts nicht erreichen kann, kann jetzt den Global Action Bar Service verwenden, um die Lautstärke zu ändern (zu erhöhen).
7. Scroll-Button konfigurieren
In diesem Abschnitt müssen Sie zwei Methoden programmieren. Bei der ersten Methode wird ein scrollbarer Knoten gesucht und bei der zweiten Methode wird die Scrollaktion im Namen des Nutzers ausgeführt.
Fügen Sie die Methode findScrollableNode zu GlobalActionBarService.java hinzu:
private AccessibilityNodeInfo findScrollableNode(AccessibilityNodeInfo root) {
Deque<AccessibilityNodeInfo> deque = new ArrayDeque<>();
deque.add(root);
while (!deque.isEmpty()) {
AccessibilityNodeInfo node = deque.removeFirst();
if (node.getActionList().contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD)) {
return node;
}
for (int i = 0; i < node.getChildCount(); i++) {
deque.addLast(node.getChild(i));
}
}
return null;
}
Bedienungshilfen haben keinen Zugriff auf die tatsächlichen Ansichten auf dem Bildschirm. Stattdessen wird eine Spiegelung des Bildschirminhalts in Form eines Baums aus AccessibilityNodeInfo-Objekten angezeigt. Diese Objekte enthalten Informationen zur Ansicht, die sie repräsentieren, z. B. den Speicherort der Ansicht, zugehörigen Text, Metadaten, die für die Barrierefreiheit hinzugefügt wurden, und von der Ansicht unterstützte Aktionen. Die Methode findScrollableNode() führt eine Breitensuche in diesem Baum aus, beginnend mit dem Stammknoten. Wenn ein scrollbarer Knoten gefunden wird (d. h. ein Knoten, der die Aktion AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD) unterstützt), wird dieser zurückgegeben.Andernfalls wird „null“ zurückgegeben.
Fügen Sie nun die Methode configureScrollButton() zu GlobalActionBarService.java hinzu:
private void configureScrollButton() {
Button scrollButton = (Button) mLayout.findViewById(R.id.scroll);
scrollButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AccessibilityNodeInfo scrollable = findScrollableNode(getRootInActiveWindow());
if (scrollable != null) {
scrollable.performAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD.getId());
}
}
});
}
Mit dieser Methode wird ein onClickListener() erstellt, der ausgelöst wird, wenn auf die Schaltfläche zum Scrollen geklickt wird. Es wird versucht, einen scrollbaren Knoten zu finden. Wenn dies gelingt, wird die Scrollaktion ausgeführt.
Fügen Sie nun configureScrollButton() zu onServiceConnected() hinzu:
@Override
protected void onServiceConnected() {
...
configureScrollButton();
}
Klicken Sie in der Menüleiste oben auf dem Bildschirm auf das grüne Play-Symbol
. Rufen Sie dann die Einstellungen > Bedienungshilfen auf und starten Sie den Global Action Bar Service.
Drücken Sie die Zurück-Taste, um zu Einstellungen > Bedienungshilfen zu gelangen. Die Elemente in den Einstellungen für Bedienungshilfen sind scrollbar. Durch Tippen auf die Schaltfläche „Scrollen“ wird eine Scrollaktion ausgeführt. Unser hypothetischer Nutzer, der Scrollvorgänge nicht einfach ausführen kann, kann jetzt mit der Schaltfläche „Scrollen“ durch eine Liste von Elementen scrollen.
8. Wisch-Schaltfläche konfigurieren
Fügen Sie die Methode configureSwipeButton() zu GlobalActionBarService.java hinzu:
private void configureSwipeButton() {
Button swipeButton = (Button) mLayout.findViewById(R.id.swipe);
swipeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Path swipePath = new Path();
swipePath.moveTo(1000, 1000);
swipePath.lineTo(100, 1000);
GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
gestureBuilder.addStroke(new GestureDescription.StrokeDescription(swipePath, 0, 500));
dispatchGesture(gestureBuilder.build(), null, null);
}
});
}
Die Methode configureSwipeButton() verwendet eine neue API, die in N hinzugefügt wurde und mit der im Namen des Nutzers Gesten ausgeführt werden. Im Code wird ein GestureDescription-Objekt verwendet, um den Pfad für die auszuführende Geste anzugeben (in diesem Codelab werden hartcodierte Werte verwendet). Anschließend wird die Wischgeste im Namen des Nutzers mit der Methode dispatchGesture() des AccessibilityService gesendet.
Fügen Sie nun configureSwipeButton() zu onServiceConnected() hinzu:
@Override
protected void onServiceConnected() {
...
configureSwipeButton();
}
Klicken Sie in der Menüleiste oben auf dem Bildschirm auf das grüne Play-Symbol
. Rufen Sie dann die Einstellungen > Bedienungshilfen auf und starten Sie den Global Action Bar Service.
Die Wischfunktion lässt sich am einfachsten testen, indem Sie die auf Ihrem Smartphone installierte Google Maps App öffnen. Sobald die Karte geladen ist, wird durch Tippen auf die Schaltfläche „Wischen“ der Bildschirm nach rechts gewischt.
9. Zusammenfassung
Glückwunsch! Sie haben einen einfachen, funktionalen Bedienungshilfendienst erstellt.
Sie können diesen Dienst auf verschiedene Arten erweitern. Beispiel:
- Die Aktionsleiste soll verschiebbar sein (derzeit befindet sie sich nur oben auf dem Bildschirm).
- Der Nutzer kann die Lautstärke sowohl erhöhen als auch verringern.
- Dem Nutzer erlauben, sowohl nach links als auch nach rechts zu wischen.
- Unterstützung für zusätzliche Gesten hinzufügen, auf die die Aktionsleiste reagieren kann.
In diesem Codelab wird nur ein kleiner Teil der Funktionen behandelt, die von den Barrierefreiheits-APIs bereitgestellt werden. Die API deckt auch Folgendes ab (unvollständige Liste):
- Unterstützung für mehrere Fenster.
- Unterstützung für AccessibilityEvents. Wenn sich die Benutzeroberfläche ändert, werden Bedienungshilfen über AccessibilityEvent-Objekte über diese Änderungen benachrichtigt. Der Dienst kann dann entsprechend auf die Änderungen der Benutzeroberfläche reagieren.
- Vergrößerung steuern
In diesem Codelab erfahren Sie, wie Sie eine Bedienungshilfe schreiben. Wenn Sie einen Nutzer mit bestimmten Barrierefreiheitsproblemen kennen, die Sie angehen möchten, können Sie jetzt einen Dienst entwickeln, der diesem Nutzer hilft.