Membuat layanan aksesibilitas Anda sendiri

Layanan aksesibilitas adalah aplikasi yang memberikan penyempurnaan antarmuka pengguna untuk membantu pengguna dengan disabilitas, atau orang yang mungkin tidak dapat berinteraksi sepenuhnya dengan perangkat untuk sementara waktu. Misalnya, pengguna yang sedang mengemudi, merawat anak kecil, atau menghadiri pesta yang sangat ramai mungkin memerlukan masukan antarmuka tambahan atau alternatif.

Android akan menyediakan layanan aksesibilitas standar, termasuk TalkBack, sedangkan developer dapat membuat dan mendistribusikan layanan mereka sendiri. Dokumen ini menjelaskan dasar-dasar pembuatan layanan aksesibilitas.

Catatan: Aplikasi Anda harus menggunakan layanan aksesibilitas tingkat platform, yang hanya bertujuan membantu pengguna dengan disabilitas untuk berinteraksi dengan aplikasi Anda.

Kemampuan untuk membuat dan men-deploy layanan aksesibilitas telah diperkenalkan pada Android 1.6 (API Level 4) dan memperoleh peningkatan yang signifikan pada Android 4.0 (API Level 14). Android Support Library juga diupdate dengan rilis Android 4.0 guna memberikan dukungan untuk fitur aksesibilitas yang disempurnakan ini ke Android 1.6 sebelumnya. Developer yang ingin menghadirkan layanan aksesibilitas yang kompatibel dengan berbagai versi dianjurkan untuk menggunakan Support Library dan mengembangkan fitur aksesibilitas yang lebih canggih, yang diperkenalkan di Android 4.0.

Membuat layanan aksesibilitas Anda

Layanan aksesibilitas dapat dipaketkan dengan aplikasi umum atau dibuat sebagai project Android mandiri. Langkah untuk membuat layanan dalam kedua situasi tersebut sama. Dalam project, buat class yang memperluas AccessibilityService.

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() {
    }

...
}

Jika Anda membuat project baru untuk layanan ini, dan tidak berencana memiliki aplikasi yang terkait dengan layanan, Anda dapat menghapus class aktivitas awal dari sumber.

Izin dan deklarasi manifes

Aplikasi yang menyediakan layanan aksesibilitas harus menyertakan deklarasi tertentu dalam manifes aplikasi agar diperlakukan sebagai layanan aksesibilitas oleh sistem Android. Bagian ini akan menjelaskan setelan wajib dan opsional untuk layanan aksesibilitas.

Deklarasi layanan aksesibilitas

Agar diperlakukan sebagai layanan aksesibilitas, Anda harus menyertakan elemen service (bukan elemen activity) dalam elemen application di manifes Anda. Selain itu, Anda juga harus menyertakan filter intent layanan aksesibilitas dalam elemen service. Agar kompatibel dengan Android 4.1 dan yang lebih tinggi, manifes juga harus melindungi layanan dengan menambahkan izin BIND_ACCESSIBILITY_SERVICE untuk memastikan bahwa hanya sistem yang dapat terikat ke layanan. Berikut contohnya:

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

Deklarasi ini diperlukan bagi semua layanan aksesibilitas yang di-deploy di Android 1.6 (API Level 4) atau yang lebih tinggi.

Konfigurasi layanan aksesibilitas

Layanan aksesibilitas juga harus menyediakan konfigurasi yang menentukan jenis peristiwa aksesibilitas yang ditangani layanan serta informasi tambahan tentang layanan tersebut. Konfigurasi layanan aksesibilitas terdapat dalam class AccessibilityServiceInfo. Layanan Anda dapat membuat dan menyetel konfigurasi menggunakan instance class ini dan setServiceInfo() pada waktu proses. Namun, tidak semua opsi konfigurasi tersedia dengan metode ini.

Mulai dari Android 4.0, Anda dapat menyertakan elemen <meta-data> dalam manifes dengan referensi ke file konfigurasi, yang memungkinkan Anda menyetel rentang penuh opsi untuk layanan aksesibilitas, seperti ditunjukkan dalam contoh berikut:

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

Elemen metadata ini merujuk pada file XML yang Anda buat di direktori resource aplikasi (<project_dir>/res/xml/accessibility_service_config.xml). Kode berikut akan menampilkan konten contoh untuk file konfigurasi layanan:

<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"
/>

Untuk informasi selengkapnya tentang atribut XML yang dapat digunakan dalam file konfigurasi layanan aksesibilitas, ikuti link ke dokumentasi referensi berikut:

Untuk informasi selengkapnya tentang setelan konfigurasi yang dapat disetel secara dinamis pada waktu proses, lihat dokumentasi referensi AccessibilityServiceInfo.

Mengonfigurasi layanan aksesibilitas

Menyetel variabel konfigurasi untuk layanan aksesibilitas akan memberi tahu sistem kapan dan bagaimana Anda ingin menjalankannya. Jenis peristiwa seperti apa yang ingin Anda respons? Haruskah layanan aktif untuk semua aplikasi, atau hanya nama paket tertentu? Jenis masukan apa yang digunakan?

Anda memiliki dua opsi untuk menyetel variabel ini. Opsi kompatibilitas mundur digunakan untuk menyetel variabel dalam kode, menggunakan setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo). Untuk melakukannya, ganti metode onServiceConnected() dan konfigurasikan layanan Anda di dalamnya.

Kotlin

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

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

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

        // Default services are invoked only if no package-specific ones are present
        // for the type of AccessibilityEvent generated. This service *is*
        // application-specific, so the flag isn't necessary. If this was a
        // general-purpose service, it would be worth considering 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
    // won't be passed to this service.
    info.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED |
            AccessibilityEvent.TYPE_VIEW_FOCUSED;

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

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

    // Default services are invoked only if no package-specific ones are present
    // for the type of AccessibilityEvent generated. This service *is*
    // application-specific, so the flag isn't necessary. If this was a
    // general-purpose service, it would be worth considering setting the
    // DEFAULT flag.

    // info.flags = AccessibilityServiceInfo.DEFAULT;

    info.notificationTimeout = 100;

    this.setServiceInfo(info);

}

Opsi kedua adalah mengonfigurasi layanan menggunakan file XML. Opsi konfigurasi tertentu seperti canRetrieveWindowContent hanya tersedia jika Anda mengonfigurasi layanan menggunakan XML. Opsi konfigurasi yang sama di atas, yang ditentukan menggunakan XML, akan terlihat seperti ini:

<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"
/>

Jika membuka rute XML, pastikan Anda merujuknya dalam manifes, dengan menambahkan tag <meta-data> ke deklarasi layanan, yang mengarah ke file XML. Jika Anda menyimpan file XML di res/xml/serviceconfig.xml, tag baru akan terlihat seperti ini:

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

Metode layanan aksesibilitas

Layanan aksesibilitas harus memperluas class AccessibilityService dan mengganti metode berikut dari class tersebut. Metode ini ditunjukkan dalam urutan panggilan oleh sistem Android, mulai dari saat layanan dimulai (onServiceConnected()), saat dijalankan (onAccessibilityEvent(), onInterrupt()), hingga saat dinonaktifkan (onUnbind()).

  • onServiceConnected() - (opsional) Sistem akan memanggil metode ini saat berhasil terhubung ke layanan aksesibilitas Anda. Gunakan metode ini untuk melakukan langkah penyiapan satu kali bagi layanan Anda, termasuk menghubungkan ke layanan sistem masukan pengguna, seperti pengelola audio atau penggetar perangkat. Jika Anda ingin menyetel konfigurasi layanan pada waktu proses atau membuat penyesuaian satu kali, metode ini adalah lokasi yang mudah digunakan untuk memanggil setServiceInfo().
  • onAccessibilityEvent() - (wajib) Metode ini dipanggil kembali oleh sistem saat mendeteksi AccessibilityEvent yang cocok dengan parameter pemfilteran peristiwa yang ditentukan oleh layanan aksesibilitas Anda. Misalnya, saat pengguna mengklik tombol atau berfokus pada kontrol antarmuka pengguna dalam aplikasi yang diberikan masukan oleh layanan aksesibilitas Anda. Saat hal tersebut terjadi, sistem akan memanggil metode ini, meneruskan AccessibilityEvent terkait, yang kemudian dapat diinterpretasikan dan digunakan oleh layanan untuk memberikan masukan kepada pengguna. Metode ini dapat dipanggil beberapa kali selama siklus proses layanan Anda.
  • onInterrupt() - (wajib) Metode ini dipanggil saat sistem ingin mengganggu masukan yang diberikan layanan Anda, biasanya sebagai respons terhadap tindakan pengguna seperti memindahkan fokus ke kontrol yang berbeda. Metode ini dapat dipanggil beberapa kali selama siklus proses layanan Anda.
  • onUnbind() - (opsional) Metode ini dipanggil saat sistem akan menonaktifkan layanan aksesibilitas. Gunakan metode ini untuk melakukan prosedur penonaktifan satu kali, termasuk membatalkan alokasi layanan sistem masukan pengguna, seperti pengelola audio atau penggetar perangkat.

Metode callback ini menyediakan struktur dasar untuk layanan aksesibilitas Anda. Anda dapat menentukan cara memproses data yang diberikan oleh sistem Android dalam bentuk objek AccessibilityEvent dan memberikan masukan kepada pengguna. Untuk informasi selengkapnya tentang mendapatkan informasi dari peristiwa aksesibilitas, lihat Mendapatkan detail peristiwa.

Mendaftar untuk peristiwa aksesibilitas

Salah satu fungsi terpenting dari parameter konfigurasi layanan aksesibilitas adalah memungkinkan Anda untuk menentukan jenis peristiwa aksesibilitas yang dapat ditangani layanan Anda. Dengan menentukan informasi ini, layanan aksesibilitas dapat bekerja sama satu sama lain, dan Anda, sebagai developer, dapat menangani jenis peristiwa tertentu dari aplikasi tertentu saja secara fleksibel. Pemfilteran peristiwa dapat mencakup kriteria berikut:

  • Nama Paket - Tentukan nama paket aplikasi yang peristiwa aksesibilitasnya ingin ditangani oleh layanan Anda. Jika parameter ini dihilangkan, layanan aksesibilitas Anda akan dianggap tersedia untuk peristiwa aksesibilitas layanan bagi aplikasi apa pun. Parameter ini dapat disetel dalam file konfigurasi layanan aksesibilitas dengan atribut android:packageNames sebagai daftar yang dipisahkan koma, atau disetel menggunakan anggota AccessibilityServiceInfo.packageNames.
  • Jenis Peristiwa - Tentukan jenis peristiwa aksesibilitas yang ingin ditangani oleh layanan Anda. Parameter ini dapat disetel dalam file konfigurasi layanan aksesibilitas dengan atribut android:accessibilityEventTypes sebagai daftar yang dipisahkan karakter | (misalnya accessibilityEventTypes="typeViewClicked|typeViewFocused"), atau disetel menggunakan anggota AccessibilityServiceInfo.eventTypes.

Saat menyiapkan layanan aksesibilitas, pertimbangkan dengan cermat peristiwa yang dapat ditangani layanan Anda dan hanya daftarkan untuk peristiwa tersebut. Karena pengguna dapat mengaktifkan lebih dari satu layanan aksesibilitas dalam satu waktu, layanan Anda tidak boleh menggunakan peristiwa yang tidak dapat ditangani. Perlu diingat bahwa layanan lain mungkin menangani peristiwa tersebut untuk menyempurnakan pengalaman pengguna.

Volume aksesibilitas

Perangkat yang menjalankan Android 8.0 (API level 26) dan yang lebih tinggi menyertakan kategori volume STREAM_ACCESSIBILITY, yang memungkinkan Anda mengontrol volume output audio layanan aksesibilitas Anda secara independen dari suara lain pada perangkat.

Layanan aksesibilitas dapat menggunakan jenis streaming ini dengan menyetel opsi FLAG_ENABLE_ACCESSIBILITY_VOLUME. Anda kemudian dapat mengubah volume audio aksesibilitas perangkat dengan memanggil metode adjustStreamVolume() pada instance AudioManager perangkat.

Cuplikan kode berikut akan menunjukkan cara layanan aksesibilitas dapat menggunakan kategori volume STREAM_ACCESSIBILITY:

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

Untuk informasi selengkapnya, lihat video sesi Yang Baru di Aksesibilitas Android dari Google I/O 2017, mulai menit 6:35.

Pintasan aksesibilitas

Pada perangkat yang menjalankan Android 8.0 (API level 26) dan yang lebih tinggi, pengguna dapat mengaktifkan dan menonaktifkan layanan aksesibilitas pilihannya dari layar mana pun dengan menekan lama kedua tombol volume secara bersamaan. Meskipun pintasan ini akan mengaktifkan dan menonaktifkan Talkback secara default, pengguna dapat mengonfigurasi tombol untuk mengaktifkan dan menonaktifkan layanan apa pun, termasuk layanan Anda, yang diinstal di perangkat pengguna.

Agar pengguna dapat mengakses layanan aksesibilitas tertentu dari pintasan aksesibilitas, layanan perlu meminta fitur pada waktu proses, ketika layanan dimulai.

Untuk informasi selengkapnya, lihat video sesi Yang Baru di Aksesibilitas Android dari Google I/O 2017, mulai menit 13:25.

Tombol aksesibilitas

Pada perangkat yang menggunakan area navigasi yang dirender software dan menjalankan Android 8.0 (API level 26) atau yang lebih tinggi, di sisi kanan menu navigasi terdapat tombol aksesibilitas. Saat pengguna menekan tombol ini, mereka dapat memanggil salah satu dari beberapa fitur dan layanan aksesibilitas yang diaktifkan, tergantung pada konten yang saat ini ditampilkan di layar.

Agar pengguna dapat mengaktifkan layanan aksesibilitas tertentu menggunakan tombol aksesibilitas, layanan perlu menambahkan flag FLAG_REQUEST_ACCESSIBILITY_BUTTON dalam atribut android:accessibilityFlags objek AccessibilityServiceInfo. Layanan ini kemudian dapat mendaftarkan callback menggunakan registerAccessibilityButtonCallback().

Catatan: Fitur ini hanya tersedia pada perangkat yang menyediakan area navigasi yang dirender software. Layanan harus selalu menggunakan isAccessibilityButtonAvailable() dan merespons perubahan berdasarkan ketersediaan tombol aksesibilitas dengan mengimplementasikan onAvailabilityChanged(). Dengan begitu, pengguna dapat mengakses fungsionalitas layanan kapan saja, meskipun tombol aksesibilitas tidak didukung atau tidak tersedia.

Cuplikan kode berikut akan menunjukkan cara Anda dapat mengonfigurasi layanan aksesibilitas untuk merespons penekanan tombol aksesibilitas oleh pengguna:

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

Untuk informasi selengkapnya, lihat video sesi Yang Baru di Aksesibilitas Android dari Google I/O 2017, mulai menit 16:28.

Gestur sidik jari

Layanan aksesibilitas pada perangkat yang menjalankan Android 8.0 (API level 26) atau yang lebih tinggi dapat merespons mekanisme masukan alternatif, penggeseran terarah (atas, bawah, kiri, dan kanan) di sekitar area sensor sidik jari perangkat. Untuk mengonfigurasi layanan guna menerima callback terkait interaksi ini, selesaikan langkah-langkah berikut:

  1. Deklarasikan izin USE_FINGERPRINT dan kemampuan CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES.
  2. Tetapkan flag FLAG_REQUEST_FINGERPRINT_GESTURES dalam atribut android:accessibilityFlags.
  3. Daftarkan callback menggunakan registerFingerprintGestureCallback().

Catatan: Anda harus mengizinkan pengguna menonaktifkan dukungan layanan aksesibilitas untuk gestur sidik jari. Meskipun beberapa layanan aksesibilitas dapat memproses gestur sidik jari secara bersamaan, tindakan ini akan menyebabkan layanan saling bertentangan.

Perlu diingat bahwa tidak semua perangkat menyertakan sensor sidik jari. Untuk mengidentifikasi apakah perangkat mendukung sensor, gunakan metode isHardwareDetected(). Pada perangkat yang menyertakan sensor sidik jari sekalipun, layanan Anda tidak dapat menggunakan sensor tersebut jika digunakan untuk tujuan autentikasi. Untuk mengidentifikasi kapan sensor tersedia, panggil metode isGestureDetectionAvailable() dan implementasikan callback onGestureDetectionAvailabilityChanged().

Cuplikan kode berikut akan menunjukkan contoh penggunaan gestur sidik jari untuk memilih opsi navigasi di papan game virtual:

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"
    ... />

MyFingerprintGestureService.java

Kotlin

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

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

Untuk informasi selengkapnya, lihat video sesi Yang Baru di Aksesibilitas Android dari Google I/O 2017, mulai menit 9:03.

Text to speech multibahasa

Mulai Android 8.0 (API level 26), layanan text-to-speech (TTS) Android dapat mengidentifikasi dan mengucapkan frasa dalam beberapa bahasa di satu blok teks. Untuk mengaktifkan kemampuan pengalihan bahasa otomatis ini dalam layanan aksesibilitas, gabungkan semua string dalam objek LocaleSpan, seperti ditunjukkan dalam cuplikan kode berikut:

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

Untuk informasi selengkapnya, lihat video sesi Yang Baru di Aksesibilitas Android dari Google I/O 2017, mulai menit 10:59.

Mengambil tindakan untuk pengguna

Mulai Android 4.0 (API Level 14), layanan aksesibilitas dapat bertindak atas nama pengguna, termasuk mengubah fokus input dan memilih (mengaktifkan) elemen antarmuka pengguna. Di Android 4.1 (API Level 16), rentang tindakan telah diperluas untuk menyertakan daftar scroll dan berinteraksi dengan bidang teks. Layanan aksesibilitas juga dapat mengambil tindakan global, seperti menuju Layar utama, menekan tombol Kembali, serta membuka layar notifikasi dan daftar aplikasi terbaru. Android 4.1 juga menyertakan jenis fokus baru, yaitu Fokus Aksesibilitas, yang membuat semua elemen yang terlihat dapat dipilih oleh layanan aksesibilitas.

Kemampuan baru ini memungkinkan developer layanan aksesibilitas membuat mode navigasi alternatif seperti navigasi gestur, dan memberikan kontrol perangkat Android yang lebih baik kepada pengguna dengan disabilitas.

Memproses gestur

Layanan aksesibilitas dapat memproses gestur tertentu dan merespons dengan mengambil tindakan atas nama pengguna. Fitur ini ditambahkan di Android 4.1 (API Level 16), dan mengharuskan layanan aksesibilitas Anda meminta aktivasi fitur Klik untuk Info. Layanan Anda dapat meminta aktivasi ini dengan menyetel anggota flags dari instance AccessibilityServiceInfo layanan ke FLAG_REQUEST_TOUCH_EXPLORATION_MODE, seperti ditunjukkan dalam contoh berikut ini.

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

Setelah layanan Anda meminta aktivasi Klik untuk Info, pengguna harus mengizinkan fitur tersebut diaktifkan, jika belum aktif. Setelah fitur ini aktif, layanan Anda akan menerima notifikasi gestur aksesibilitas melalui metode callback onGesture() layanan dan dapat merespons dengan mengambil tindakan untuk pengguna.

Gestur berkelanjutan

Perangkat yang menjalankan Android 8.0 (API level 26) menyertakan dukungan untuk gestur berkelanjutan, atau gestur terprogram yang berisi lebih dari satu objek Path.

Saat menentukan urutan goresan, Anda harus menentukan bahwa goresan tersebut tergolong dalam gestur terprogram yang sama menggunakan argumen akhir, willContinue, dalam konstruktor GestureDescription.StrokeDescription, seperti ditunjukkan dalam cuplikan kode berikut:

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

Untuk informasi selengkapnya, lihat video sesi Yang Baru di Aksesibilitas Android dari Google I/O 2017, mulai menit 15:47.

Menggunakan tindakan aksesibilitas

Layanan aksesibilitas dapat mengambil tindakan atas nama pengguna untuk membuat interaksi dengan aplikasi menjadi lebih mudah dan lebih produktif. Kemampuan layanan aksesibilitas untuk melakukan tindakan telah ditambahkan di Android 4.0 (API Level 14) dan diperluas secara signifikan dengan Android 4.1 (API Level 16).

Agar dapat mengambil tindakan atas nama pengguna, layanan aksesibilitas Anda harus terdaftar untuk menerima peristiwa dari beberapa atau banyak aplikasi dan meminta izin untuk melihat konten aplikasi dengan menyetel android:canRetrieveWindowContent ke true dalam file konfigurasi layanan. Setelah peristiwa diterima oleh layanan Anda, layanan akan mengambil objek AccessibilityNodeInfo dari peristiwa menggunakan getSource(). Dengan objek AccessibilityNodeInfo, layanan Anda akan dapat menjelajahi hierarki tampilan untuk menentukan tindakan yang harus diambil, lalu bertindak atas nama pengguna menggunakan performAction().

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

            // take action 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

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

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

Metode performAction() memungkinkan layanan Anda mengambil tindakan dalam aplikasi. Jika layanan Anda perlu melakukan tindakan global seperti menuju Layar utama, menekan tombol Kembali, membuka layar notifikasi atau daftar aplikasi terbaru, gunakan metode performGlobalAction().

Menggunakan jenis fokus

Android 4.1 (API Level 16) memperkenalkan fokus antarmuka pengguna jenis terbaru bernama Fokus Aksesibilitas. Layanan aksesibilitas dapat menggunakan jenis fokus ini untuk memilih elemen antarmuka pengguna yang terlihat, lalu menindaklanjutinya. Jenis fokus ini berbeda dengan Fokus Masukan yang lebih umum, yang menentukan elemen antarmuka pengguna mana yang ada di layar dan menerima masukan saat pengguna mengetik karakter, menekan Enter pada keyboard, atau menekan tombol tengah kontrol D-pad.

Fokus Aksesibilitas sepenuhnya terpisah dan independen dari fokus input. Bahkan, ada kemungkinan satu elemen di antarmuka pengguna memiliki fokus input, sedangkan elemen lain memiliki Fokus Aksesibilitas. Tujuan Fokus Aksesibilitas adalah menyediakan layanan aksesibilitas dengan metode yang berinteraksi dengan elemen yang terlihat di layar, terlepas dari dapat tidaknya elemen tersebut difokuskan masukan dari perspektif sistem. Anda dapat melihat cara kerja fokus aksesibilitas dengan menguji gestur aksesibilitas. Untuk informasi selengkapnya tentang pengujian fitur ini, lihat Menguji navigasi gestur.

Catatan: Layanan aksesibilitas yang menggunakan Fokus Aksesibilitas bertanggung jawab untuk menyinkronkan fokus input saat ini jika elemen mendukung jenis fokus ini. Layanan yang tidak menyinkronkan fokus input dengan Fokus Aksesibilitas dapat berisiko menyebabkan masalah di aplikasi yang mengharapkan fokus input berada di lokasi tertentu saat tindakan tertentu dilakukan.

Layanan aksesibilitas dapat menentukan elemen antarmuka pengguna mana yang memiliki fokus input atau Fokus Aksesibilitas menggunakan metode AccessibilityNodeInfo.findFocus(). Anda juga dapat menelusuri elemen yang dapat dipilih dengan fokus input menggunakan metode focusSearch(). Terakhir, layanan aksesibilitas Anda dapat menyetel Fokus Aksesibilitas menggunakan metode performAction(AccessibilityNodeInfo.ACTION_SET_ACCESSIBILITY_FOCUS).

Mengumpulkan informasi

Layanan aksesibilitas juga memiliki metode standar untuk mengumpulkan dan merepresentasikan unit utama dari informasi yang diberikan oleh pengguna, seperti detail peristiwa, teks, dan angka.

Mendapatkan detail peristiwa

Sistem Android akan menyediakan informasi untuk layanan aksesibilitas tentang interaksi antarmuka pengguna melalui objek AccessibilityEvent. Sebelum Android 4.0, informasi tersebut tersedia dalam peristiwa aksesibilitas, sekaligus menyediakan banyak detail tentang kontrol antarmuka pengguna yang dipilih oleh pengguna, dan menawarkan informasi kontekstual yang terbatas. Dalam banyak kasus, informasi konteks yang hilang ini mungkin sangat penting untuk memahami arti kontrol yang dipilih.

Contoh antarmuka yang konteksnya sangat penting adalah kalender atau perencana harian. Jika pengguna memilih slot waktu 16.00 dalam daftar hari Senin sampai Jumat dan layanan aksesibilitas mengumumkan “jam 4 sore”, tetapi tidak mengumumkan nama hari, hari dengan tanggal khusus, atau nama bulan, hasil dari masukan tersebut akan membingungkan. Dalam hal ini, konteks dari kontrol antarmuka pengguna sangat penting bagi pengguna yang ingin menjadwalkan rapat.

Android 4.0 secara signifikan memperluas jumlah informasi yang bisa didapatkan oleh layanan aksesibilitas tentang interaksi antarmuka pengguna dengan membuat peristiwa aksesibilitas berdasarkan hierarki tampilan. Hierarki tampilan adalah kumpulan komponen antarmuka pengguna yang berisi komponen (induknya) dan elemen antarmuka pengguna yang mungkin terdapat dalam komponen tersebut (turunannya). Dengan cara ini, sistem Android dapat memberikan peristiwa aksesibilitas yang jauh lebih kaya, memungkinkan layanan aksesibilitas memberikan masukan yang lebih bermanfaat bagi pengguna.

Layanan aksesibilitas mendapatkan informasi tentang peristiwa antarmuka pengguna melalui AccessibilityEvent yang diteruskan oleh sistem ke metode callback onAccessibilityEvent() layanan. Objek ini memberikan detail tentang peristiwa, termasuk jenis objek yang sedang ditindaklanjuti, teks deskriptifnya, dan detail lainnya. Mulai Android 4.0 (dan didukung di rilis sebelumnya melalui objek AccessibilityEventCompat dalam Support Library), Anda dapat memperoleh informasi tambahan tentang peristiwa menggunakan panggilan ini:

  • AccessibilityEvent.getRecordCount() dan getRecord(int) - Metode ini memungkinkan Anda mengambil kumpulan objek AccessibilityRecord yang berkontribusi pada AccessibilityEvent yang diteruskan kepada Anda oleh sistem. Tingkat detail ini memberikan lebih banyak konteks untuk peristiwa yang memicu layanan aksesibilitas Anda.
  • AccessibilityEvent.getSource() - Metode ini akan menampilkan objek AccessibilityNodeInfo. Objek ini memungkinkan Anda meminta hierarki tata letak tampilan (induk dan turunan) komponen yang berasal dari peristiwa aksesibilitas. Fitur ini memungkinkan layanan aksesibilitas menyelidiki konteks penuh peristiwa, termasuk konten dan status tampilan yang disertakan atau tampilan turunan.

    Penting: Kemampuan untuk menyelidiki hierarki tampilan dari AccessibilityEvent berpotensi memperlihatkan informasi pengguna pribadi ke layanan aksesibilitas Anda. Untuk alasan tersebut, layanan Anda harus meminta tingkat akses ini melalui aksesibilitas file XML konfigurasi layanan, dengan menyertakan atribut canRetrieveWindowContent dan menyetelnya ke true. Jika Anda tidak menyertakan setelan ini dalam file xml konfigurasi layanan Anda, panggilan ke getSource() akan gagal.

    Catatan: Di Android 4.1 (API Level 16) dan yang lebih tinggi, metode getSource(), serta AccessibilityNodeInfo.getChild() dan getParent(), hanya menampilkan objek tampilan yang dianggap penting untuk aksesibilitas (tampilan yang menggambarkan konten atau merespons tindakan pengguna). Jika layanan Anda memerlukan semua tampilan, layanan dapat meminta tampilan tersebut dengan menyetel anggota flags dari instance AccessibilityServiceInfo layanan ke FLAG_INCLUDE_NOT_IMPORTANT_VIEWS.

Mendapatkan detail perubahan jendela

Android 9 (API level 28) dan yang lebih tinggi memungkinkan aplikasi melacak pembaruan jendela saat aplikasi menggambar ulang beberapa jendela secara bersamaan. Saat peristiwa TYPE_WINDOWS_CHANGED terjadi, gunakan getWindowChanges() API untuk menentukan bagaimana jendela berubah. Selama pembaruan multi-jendela, setiap jendela akan menghasilkan kumpulan peristiwanya sendiri. Metode getSource() akan menampilkan tampilan root jendela yang terkait dengan setiap peristiwa.

Jika aplikasi telah menentukan judul panel aksesibilitas untuk objek View-nya, layanan Anda dapat mengenali kapan UI aplikasi diperbarui. Saat peristiwa TYPE_WINDOW_STATE_CHANGED terjadi, gunakan jenis yang ditampilkan oleh getContentChangeTypes() untuk menentukan bagaimana jendela berubah. Misalnya, framework dapat mendeteksi kapan panel memiliki judul baru, atau kapan panel menghilang.

Mengumpulkan detail node aksesibilitas

Langkah ini bersifat opsional, tetapi sangat berguna. Platform Android menyediakan kemampuan bagi AccessibilityService untuk membuat kueri hierarki tampilan, mengumpulkan informasi tentang komponen UI yang menghasilkan peristiwa, serta induk dan turunannya. Untuk melakukannya, pastikan Anda menyetel baris berikut dalam konfigurasi XML Anda:

android:canRetrieveWindowContent="true"

Setelah selesai, panggil objek AccessibilityNodeInfo menggunakan getSource(). Panggilan ini hanya akan menampilkan objek jika jendela tempat peristiwa berasal masih menjadi jendela yang aktif. Jika tidak, jendela akan menampilkan null, jadi sesuaikan perilakunya. Contoh berikut adalah cuplikan kode yang, saat menerima peristiwa, melakukan hal berikut:

  1. Segera panggil induk tampilan dari tempat peristiwa berasal
  2. Dalam tampilan tersebut, cari label dan kotak centang sebagai tampilan turunan
  3. Jika menemukannya, buat string untuk dilaporkan kepada pengguna, yang menunjukkan label dan apakah label tersebut dicentang atau tidak.
  4. Jika kapan pun nilai null ditampilkan saat menjelajahi hierarki tampilan, metode akan menghentikannya secara diam-diam.

Kotlin

// Alternative onAccessibilityEvent, that uses AccessibilityNodeInfo

override fun onAccessibilityEvent(event: AccessibilityEvent) {

    val source: AccessibilityNodeInfo = event.source ?: return

    // Grab the parent of the view that fired 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 or not it's complete, based on
    // the text inside the label, and the state of the check-box.
    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 fired 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 or not it's complete, based on
    // the text inside the label, and the state of the check-box.
    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);
}

Kini Anda memiliki layanan aksesibilitas yang lengkap dan berfungsi. Coba konfigurasikan cara layanan aksesibilitas berinteraksi dengan pengguna, dengan menambahkan mesin text-to-speech Android, atau menggunakan Vibrator untuk memberikan info via sentuhan.

Memproses teks

Perangkat yang menjalankan Android 8.0 (API level 26) dan yang lebih tinggi menyertakan beberapa fitur pemrosesan teks yang mempermudah layanan aksesibilitas untuk mengidentifikasi dan mengoperasikan unit teks tertentu yang muncul di layar.

Tooltip

Android 9 (API level 28) memperkenalkan beberapa kemampuan yang memberi Anda akses ke tooltip dalam UI aplikasi. Gunakan getTooltipText() untuk membaca teks tooltip, dan gunakan ACTION_SHOW_TOOLTIP dan ACTION_HIDE_TOOLTIP untuk menginstruksikan instance View guna menampilkan atau menyembunyikan tooltipnya.

Teks petunjuk

Android 8.0 (API level 26) menyertakan beberapa metode untuk berinteraksi dengan teks petunjuk objek berbasis teks:

  • Metode isShowingHintText() dan setShowingHintText() menunjukkan dan menyetel, secara berurutan, apakah konten teks node saat ini merepresentasikan teks petunjuk node.
  • Untuk mengakses teks petunjuk itu sendiri, gunakan getHintText(). Meskipun objek saat ini tidak menampilkan teks petunjuk, panggilan ke getHintText() akan tetap berhasil.

Lokasi karakter teks di layar

Pada perangkat yang menjalankan Android 8.0 (API level 26) dan yang lebih tinggi, layanan aksesibilitas dapat menentukan koordinat layar untuk setiap kotak pembatas karakter yang terlihat dalam widget TextView. Layanan akan menemukan koordinat ini dengan memanggil refreshWithExtraData(), meneruskan EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY sebagai argumen pertama dan objek Bundle sebagai argumen kedua. Setelah metode dieksekusi, sistem akan mengisi argumen Bundle dengan array parcelable dari objek Rect. Setiap objek Rect merepresentasikan kotak pembatas karakter tertentu.

Nilai rentang satu sisi standar

Beberapa objek AccessibilityNodeInfo menggunakan instance AccessibilityNodeInfo.RangeInfo untuk menunjukkan bahwa elemen UI dapat berisi rentang nilai. Saat membuat rentang menggunakan RangeInfo.obtain(), atau saat mengambil nilai ekstrem dari rentang menggunakan getMin() dan getMax(), perlu diperhatikan bahwa perangkat yang menjalankan Android 8.0 (API level 26) dan yang lebih tinggi merepresentasikan rentang satu sisi secara standar:

Merespons peristiwa aksesibilitas

Setelah layanan Anda disiapkan untuk menjalankan dan memproses peristiwa, tulis beberapa kode agar layanan mengetahui tindakan apa yang harus dilakukan saat AccessibilityEvent tersedia. Mulai dengan mengganti metode onAccessibilityEvent(AccessibilityEvent). Dalam metode tersebut, gunakan getEventType() untuk menentukan jenis peristiwa, dan getContentDescription() untuk mengekstrak teks label apa pun yang terkait dengan tampilan yang mengaktifkan peristiwa tersebut.

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

Referensi tambahan

Untuk mempelajari lebih lanjut, manfaatkan referensi berikut:

Codelab