1. Pengantar
Layanan aksesibilitas adalah fitur framework Android yang dirancang untuk memberikan masukan navigasi alternatif kepada pengguna atas nama aplikasi yang diinstal di perangkat Android. Layanan aksesibilitas dapat berkomunikasi dengan pengguna atas nama aplikasi, misalnya dengan mengonversi teks menjadi ucapan atau memberikan umpan balik haptik saat pengguna mengarahkan kursor ke area penting di layar. Codelab ini menunjukkan cara membuat layanan aksesibilitas yang sangat sederhana.
Apa yang dimaksud dengan Layanan Aksesibilitas?
Layanan Aksesibilitas membantu pengguna difabel dalam menggunakan perangkat dan aplikasi Android. Layanan ini adalah layanan istimewa yang berjalan lama dan membantu pengguna memproses informasi di layar serta memungkinkan mereka berinteraksi dengan perangkat secara bermakna.
Contoh layanan aksesibilitas umum
- Tombol Akses: memungkinkan pengguna Android dengan keterbatasan mobilitas berinteraksi dengan perangkat menggunakan satu atau beberapa tombol.
- Voice Access (beta): memungkinkan pengguna Android dengan keterbatasan mobilitas mengontrol perangkat dengan perintah lisan.
- TalkBack: pembaca layar yang umum digunakan oleh pengguna tunanetra atau penyandang gangguan penglihatan.
Membangun layanan aksesibilitas
Meskipun Google menyediakan layanan seperti Tombol Akses, Akses Suara, dan Talkback untuk pengguna Android, layanan ini tidak mungkin melayani semua pengguna penyandang disabilitas. Karena banyak pengguna penyandang disabilitas memiliki kebutuhan yang unik, API Android untuk membuat layanan aksesibilitas bersifat terbuka, dan developer bebas membuat layanan aksesibilitas serta mendistribusikannya melalui Play Store.
Yang akan Anda bangun
Dalam codelab ini, Anda akan mengembangkan layanan sederhana yang melakukan beberapa hal berguna menggunakan API aksesibilitas. Jika Anda dapat menulis aplikasi Android dasar, Anda dapat mengembangkan layanan serupa.
API aksesibilitas sangat canggih: kode untuk layanan yang akan Anda buat hanya terdapat dalam empat file, dan menggunakan ~200 baris kode.
Pengguna akhir
Anda akan membangun layanan untuk pengguna hipotetis dengan karakteristik berikut:
- Pengguna kesulitan menjangkau tombol samping di perangkat.
- Pengguna kesulitan men-scroll atau menggeser.
Detail layanan
Layanan Anda akan menempatkan panel tindakan global di layar. Pengguna dapat menyentuh tombol di panel ini untuk melakukan tindakan berikut:
- Nonaktifkan perangkat tanpa menyentuh tombol daya di samping ponsel.
- Sesuaikan volume tanpa menyentuh tombol volume di sisi ponsel.
- Lakukan tindakan scroll tanpa benar-benar men-scroll.
- Melakukan geser tanpa harus menggunakan gestur geser.
Yang Anda butuhkan
Codelab ini mengasumsikan Anda akan menggunakan hal berikut:
- Komputer yang menjalankan Android Studio.
- Terminal untuk menjalankan perintah shell sederhana.
- Perangkat yang menjalankan Android 7.0 (Nougat) yang terhubung ke komputer yang akan Anda gunakan untuk pengembangan.
Mari kita mulai!
2. Mempersiapkan
Dengan menggunakan terminal, buat direktori tempat Anda akan bekerja. Ubah ke direktori ini.
Download Kode
Anda dapat meng-clone repositori yang berisi kode untuk codelab ini:
git clone https://github.com/android/codelab-android-accessibility.git
Repositori ini berisi beberapa project Android Studio. Dengan menggunakan Android Studio, buka GlobalActionBarService.
Luncurkan Android Studio dengan mengklik ikon Studio:

Pilih opsi Import project (Eclipse ADT, Gradle, etc.):

Buka lokasi tempat Anda meng-clone sumber, lalu pilih GlobalActionBarService.
Kemudian, menggunakan terminal, ubah ke direktori root.
3. Memahami kode awal
Jelajahi project yang telah Anda buka.
Kerangka dasar untuk layanan aksesibilitas telah dibuat untuk Anda. Semua kode yang akan Anda tulis dalam codelab ini terbatas pada empat file berikut:
- 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
Berikut adalah panduan isi setiap file.
AndroidManifest.xml
Informasi tentang layanan aksesibilitas dideklarasikan dalam manifes:
<?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>
Tiga item wajib berikut dideklarasikan di AndroidManifest.xml:
- Izin untuk mengikat ke layanan aksesibilitas:
<service
...
android:permission = "android.permission.BIND_ACCESSIBILITY_SERVICE">
...
</service>
- Intent AccessibilityService:
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
- Lokasi file yang berisi metadata untuk layanan yang Anda buat:
<meta-data
...
android:resource="@xml/global_action_bar_service" />
</service>
global_action_bar_service.xml
File ini berisi metadata untuk layanan.
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagDefault"
android:canPerformGestures="true"
android:canRetrieveWindowContent="true" />
Dengan menggunakan elemen <accessibility-service>, metadata berikut telah ditentukan:
- Jenis masukan untuk layanan ini (codelab ini menggunakan feedbackGeneric, yang merupakan default yang baik).
- Flag aksesibilitas untuk layanan (codelab ini menggunakan flag default).
- Kemampuan yang diperlukan untuk layanan:
- Untuk melakukan geser, android:canPerformGestures ditetapkan ke true.
- Untuk mengambil konten jendela, android:canRetrieveWindowContent disetel ke true.
GlobalActionBarService.java
Sebagian besar kode untuk layanan aksesibilitas berada di GlobalActionBarService.java. Awalnya, file berisi kode minimum mutlak untuk layanan aksesibilitas:
- Class yang memperluas AccessibilityService.
- Beberapa metode yang diganti dan wajib diisi (dikosongkan dalam codelab ini).
public class GlobalActionBarService extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
}
@Override
public void onInterrupt() {
}
}
Anda akan menambahkan kode ke file ini selama codelab.
action_bar.xml
Layanan ini menampilkan UI dengan empat tombol, dan file tata letak action_bar.xml berisi markup untuk menampilkan tombol tersebut:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
File ini berisi LinearLayout kosong untuk saat ini. Anda akan menambahkan markup untuk tombol selama codelab.
Meluncurkan aplikasi
Pastikan perangkat terhubung ke komputer Anda. Tekan ikon hijau Play
dari panel menu ke bagian atas layar. Tindakan ini akan meluncurkan aplikasi yang sedang Anda kerjakan.
Buka Setelan > Aksesibilitas. Global Action Bar Service diinstal di perangkat Anda.

Klik Global Action Bar Service dan aktifkan. Anda akan melihat dialog izin berikut:

Layanan aksesibilitas meminta izin untuk mengamati tindakan pengguna, mengambil konten jendela, dan melakukan gestur atas nama pengguna. Saat menggunakan layanan aksesibilitas pihak ketiga, pastikan Anda benar-benar memercayai sumbernya.
Menjalankan layanan tidak akan melakukan banyak hal, karena kita belum menambahkan fungsi apa pun. Mari kita mulai.
4. Membuat tombol
Buka action_bar.xml di res/layout. Tambahkan markup di dalam LinearLayout yang saat ini kosong:
<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>
Tindakan ini akan membuat tombol yang akan ditekan pengguna untuk memicu tindakan di perangkat.
Buka GlobalActionBarService.java dan tambahkan variabel untuk menyimpan tata letak panel tindakan:
public class GlobalActionBarService extends AccessibilityService {
FrameLayout mLayout;
...
}
Sekarang tambahkan metode onServiceStarted():
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);
}
}
Kode ini meng-inflate tata letak dan menambahkan panel tindakan di bagian atas layar.
Metode onServiceConnected() berjalan saat layanan terhubung. Pada saat ini, layanan aksesibilitas memiliki semua izin yang diperlukan agar dapat berfungsi. Izin utama yang akan Anda gunakan di sini adalah izin WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY. Izin ini memungkinkan Anda menggambar langsung di layar di atas konten yang ada tanpa harus melalui alur izin yang rumit.
Siklus proses Layanan Aksesibilitas
Siklus proses layanan aksesibilitas dikelola secara eksklusif oleh sistem dan mengikuti siklus proses layanan yang telah ditetapkan.
- Layanan aksesibilitas dimulai saat pengguna secara eksplisit mengaktifkan layanan di setelan perangkat.
- Setelah sistem terikat ke layanan, sistem akan memanggil onServiceConnected(). Metode ini dapat diganti oleh layanan yang ingin melakukan penyiapan setelah pengikatan.
- Layanan aksesibilitas berhenti saat pengguna menonaktifkannya di setelan perangkat atau saat layanan tersebut memanggil disableSelf().
Menjalankan layanan
Sebelum dapat meluncurkan layanan menggunakan Android Studio, Anda harus memastikan bahwa setelan Run dikonfigurasi dengan benar.
Edit konfigurasi Run Anda (gunakan Run dari menu atas, lalu buka Edit Configurations. Kemudian, menggunakan dropdown, ubah Opsi Peluncuran dari "Aktivitas Default" menjadi "Tidak Ada".

Sekarang Anda dapat meluncurkan layanan menggunakan Android Studio.
Tekan ikon hijau Play
dari panel menu ke bagian atas layar. Kemudian, buka Setelan > Aksesibilitas dan aktifkan Layanan Panel Tindakan Global.
Anda akan melihat empat tombol yang membentuk overlay UI layanan di atas konten yang ditampilkan di layar.

Sekarang Anda akan menambahkan fungsi ke empat tombol, sehingga pengguna dapat menyentuhnya untuk melakukan tindakan yang berguna.
5. Mengonfigurasi tombol Daya
Tambahkan metode configurePowerButton() ke GlobalActionBarService.java:
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);
}
});
}
Untuk akses ke menu tombol daya, configurePowerButton() menggunakan metode performGlobalAction(), yang disediakan oleh AccessibilityService. Kode yang baru saja Anda tambahkan sederhana: mengklik tombol akan memicu onClickListener(). Ini akan memanggil performGlobalAction(GLOBAL_ACTION_POWER_DIALOG) dan menampilkan dialog daya kepada pengguna.
Perhatikan bahwa tindakan global tidak terikat ke tampilan apa pun. Menekan tombol Kembali, tombol Layar utama, tombol Terbaru adalah contoh tindakan global lainnya.
Sekarang tambahkan configurePowerButton() di akhir metode onServiceConnected():
@Override
protected void onServiceConnected() {
...
configurePowerButton();
}
Tekan ikon hijau Play
dari panel menu ke bagian atas layar. Kemudian, buka Setelan > Aksesibilitas dan mulai Layanan Panel Tindakan Global.
Tekan tombol Daya untuk menampilkan dialog daya.
6. Mengonfigurasi Tombol Volume
Tambahkan metode configureVolumeButton() ke GlobalActionBarService.java:
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);
}
});
}
Metode configureVolumeButton() menambahkan onClickListener() yang dipicu saat pengguna menekan tombol volume. Di dalam pemroses ini, configureVolumeButton() menggunakan AudioManager untuk menyesuaikan volume stream.
Perhatikan bahwa siapa pun dapat mengontrol volume (Anda tidak perlu menjadi layanan aksesibilitas untuk melakukannya).
Sekarang tambahkan configureVolumeButton() di akhir metode onServiceConnected():
@Override
protected void onServiceConnected() {
...
configureVolumeButton();
}
Tekan ikon hijau Play
dari panel menu ke bagian atas layar. Kemudian, buka Setelan > Aksesibilitas dan mulai Layanan Panel Tindakan Global.
Tekan tombol Volume untuk mengubah volume.
Pengguna hipotetis yang tidak dapat menjangkau kontrol volume di samping perangkat kini dapat menggunakan Layanan Panel Tindakan Global untuk mengubah (menaikkan) volume.
7. Mengonfigurasi Tombol Scroll
Bagian ini melibatkan pengodean dua metode. Metode pertama menemukan node yang dapat di-scroll, dan metode kedua melakukan tindakan scroll atas nama pengguna.
Tambahkan metode findScrollableNode ke GlobalActionBarService.java:
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;
}
Layanan aksesibilitas tidak memiliki akses ke tampilan sebenarnya di layar. Sebagai gantinya, ia melihat pantulan dari apa yang ada di layar dalam bentuk hierarki yang terdiri dari objek AccessibilityNodeInfo. Objek ini berisi informasi tentang tampilan yang diwakilinya (lokasi tampilan, teks apa pun yang terkait dengan tampilan, metadata yang telah ditambahkan untuk aksesibilitas, tindakan yang didukung oleh tampilan, dll.). Metode findScrollableNode() melakukan traversal breadth-first pada hierarki ini, dimulai dari node root. Jika menemukan node yang dapat di-scroll (yaitu, node yang mendukung AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD action), node tersebut akan ditampilkan, jika tidak, null akan ditampilkan.
Sekarang tambahkan metode configureScrollButton() ke GlobalActionBarService.java:
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());
}
}
});
}
Metode ini membuat onClickListener() yang diaktifkan saat tombol scroll diklik. Tindakan ini mencoba menemukan node yang dapat di-scroll dan jika berhasil, akan melakukan tindakan scroll.
Sekarang tambahkan configureScrollButton() ke onServiceConnected():
@Override
protected void onServiceConnected() {
...
configureScrollButton();
}
Tekan ikon hijau Play
dari panel menu ke bagian atas layar. Kemudian, buka Setelan > Aksesibilitas dan mulai Layanan Panel Tindakan Global.
Tekan tombol kembali untuk membuka Setelan > Aksesibilitas. Item pada aktivitas setelan aksesibilitas dapat di-scroll, dan menyentuh tombol Scroll akan melakukan tindakan scroll. Pengguna hipotetis kita yang tidak dapat melakukan tindakan scroll dengan mudah kini dapat menggunakan tombol Scroll untuk men-scroll daftar item.
8. Mengonfigurasi Tombol Geser
Tambahkan metode configureSwipeButton() ke GlobalActionBarService.java:
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);
}
});
}
Metode configureSwipeButton() menggunakan API baru yang ditambahkan di N yang melakukan gestur atas nama pengguna. Kode menggunakan objek GestureDescription untuk menentukan jalur gestur yang akan dilakukan (nilai hardcode digunakan dalam codelab ini), lalu mengirimkan gestur geser atas nama pengguna menggunakan metode dispatchGesture() AccessibilityService.
Sekarang tambahkan configureSwipeButton() ke onServiceConnected():
@Override
protected void onServiceConnected() {
...
configureSwipeButton();
}
Tekan ikon hijau Play
dari panel menu ke bagian atas layar. Kemudian, buka Setelan > Aksesibilitas dan mulai Layanan Panel Tindakan Global.
Cara termudah untuk menguji fungsi geser adalah dengan membuka aplikasi Maps yang diinstal di ponsel Anda. Setelah peta dimuat, menyentuh tombol Geser akan menggeser layar ke kanan.
9. Ringkasan
Selamat! Anda telah membuat layanan aksesibilitas yang sederhana dan berfungsi.
Anda dapat memperluas layanan ini dengan berbagai cara. Contoh:
- Buat panel tindakan dapat dipindahkan (saat ini hanya berada di bagian atas layar).
- Izinkan pengguna untuk menambah dan mengurangi volume.
- Izinkan pengguna menggeser ke kiri dan kanan.
- Menambahkan dukungan untuk gestur tambahan yang dapat direspons oleh panel tindakan.
Codelab ini hanya mencakup sebagian kecil fungsi yang disediakan oleh API aksesibilitas. API ini juga mencakup hal-hal berikut (daftar sebagian):
- Dukungan untuk beberapa jendela.
- Dukungan untuk AccessibilityEvent. Saat UI berubah, layanan aksesibilitas akan diberi tahu tentang perubahan tersebut menggunakan objek AccessibilityEvent. Layanan kemudian dapat merespons perubahan UI sebagaimana mestinya.
- Kemampuan untuk mengontrol perbesaran.
Codelab ini membantu Anda memulai penulisan layanan aksesibilitas. Jika Anda mengetahui pengguna dengan masalah aksesibilitas tertentu yang ingin Anda tangani, Anda kini dapat membuat layanan untuk membantu pengguna tersebut.