Membuat layanan aksesibilitas Anda sendiri

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

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

Catatan: Aplikasi Anda harus menggunakan layanan aksesibilitas tingkat platform hanya untuk tujuan membantu pengguna difabel berinteraksi dengan aplikasi Anda.

Kemampuan untuk membuat dan menerapkan layanan aksesibilitas telah diperkenalkan pada Android 1.6 (API Level 4) dan memperoleh penyempurnaan yang signifikan pada Android 4.0 (API Level 14). Android Support Library juga diupdate dengan rilis Android 4.0 untuk memberikan dukungan untuk fitur aksesibilitas yang disempurnakan 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 kompleks 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 tersebut sama dalam kedua situasi tersebut. Dalam project Anda, 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 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 untuk 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 dan informasi tambahan tentang layanan tersebut. Konfigurasi layanan aksesibilitas terdapat dalam class AccessibilityServiceInfo. Layanan Anda dapat membuat dan menetapkan 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> di manifes dengan referensi ke file konfigurasi, yang memungkinkan Anda menetapkan rentang penuh opsi untuk layanan aksesibilitas, seperti yang ditunjukkan pada contoh berikut:

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

Elemen metadata ini mengacu ke file XML yang Anda buat di direktori resource aplikasi Anda (<project_dir>/res/xml/accessibility_service_config.xml). Kode berikut menampilkan contoh konten 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

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

Anda memiliki dua opsi untuk menetapkan variabel ini. Opsi kompatibilitas mundur digunakan untuk menetapkan 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 Anda membuka rute XML, pastikan untuk 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 direpresentasikan dalam urutan dipanggilnya oleh sistem Android, mulai dari saat layanan dimulai (onServiceConnected()), saat layanan dijalankan (onAccessibilityEvent(), onInterrupt()), hingga saat layanan dinonaktifkan (onUnbind()).

  • onServiceConnected() - (opsional) Sistem ini memanggil metode ini saat berhasil tersambung ke layanan aksesibilitas Anda. Gunakan metode ini untuk melakukan langkah penyiapan satu kali apa pun untuk layanan Anda, termasuk menghubungkan ke layanan sistem masukan pengguna, seperti pengelola audio atau vibrator perangkat. Jika Anda ingin menyetel konfigurasi layanan saat 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 ditafsirkan 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 vibrator perangkat.

Metode callback ini menyediakan struktur dasar untuk layanan aksesibilitas Anda. Anda dapat memutuskan 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 paling penting dari parameter konfigurasi layanan aksesibilitas adalah Anda dapat 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 secara fleksibel dapat menangani jenis peristiwa tertentu dari aplikasi tertentu saja. 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 dianggap tersedia untuk peristiwa aksesibilitas layanan untuk aplikasi apa pun. Parameter ini dapat ditetapkan dalam file konfigurasi layanan aksesibilitas dengan atribut android:packageNames sebagai daftar yang dipisahkan koma, atau ditetapkan menggunakan anggota AccessibilityServiceInfo.packageNames.
  • Jenis Peristiwa - Tentukan jenis peristiwa aksesibilitas yang ingin ditangani oleh layanan Anda. Parameter ini dapat ditentukan dalam file konfigurasi layanan aksesibilitas dengan atribut android:accessibilityEventTypes sebagai daftar yang dipisahkan karakter | (misalnya accessibilityEventTypes="typeViewClicked|typeViewFocused"), atau ditetapkan 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. Perhatikan 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 menetapkan opsi FLAG_ENABLE_ACCESSIBILITY_VOLUME. Anda kemudian dapat mengubah volume audio aksesibilitas perangkat dengan memanggil metode adjustStreamVolume() pada instance perangkat AudioManager.

Cuplikan kode berikut 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 ke 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 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 saat waktu proses, ketika layanan dimulai.

Untuk informasi selengkapnya, lihat video sesi Yang Baru di Aksesibilitas Android dari Google I/O 2017, mulai menit ke 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, bergantung 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 selalu mengakses fungsionalitas layanan, meskipun tombol aksesibilitas tidak didukung atau tidak tersedia.

Cuplikan kode berikut menunjukkan cara mengonfigurasi layanan aksesibilitas untuk merespons penekanan tombol aksesibilitas 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 ke 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 di dalam atribut android:accessibilityFlags.
  3. Daftarkan callback menggunakan registerFingerprintGestureCallback().

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

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

Cuplikan kode berikut menunjukkan contoh penggunaan gestur sidik jari untuk bernavigasi di game papan 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 ke 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 dalam satu blok teks. Untuk mengaktifkan kemampuan pengalihan bahasa otomatis ini dalam layanan aksesibilitas, gabungkan semua string dalam objek LocaleSpan, seperti yang 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 ke 10:59.

Mengambil tindakan untuk pengguna

Dimulai dari 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), beberapa tindakan telah diperluas untuk menyertakan daftar scroll dan berinteraksi dengan bidang teks. Layanan aksesibilitas juga dapat mengambil tindakan global, seperti bernavigasi ke 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 untuk membuat mode navigasi alternatif seperti navigasi gestur, dan memberi pengguna difabel kontrol yang lebih baik untuk layanan Android mereka.

Mendengarkan 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 menetapkan anggota flags dari instance AccessibilityServiceInfo layanan ke FLAG_REQUEST_TOUCH_EXPLORATION_MODE, seperti yang ditunjukkan pada contoh berikut.

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 Anda 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 bentuk garis, Anda harus menentukan bahwa bentuk garis tersebut tergolong dalam gestur terprogram yang sama dengan menggunakan argumen akhir, willContinue, dalam konstruktor GestureDescription.StrokeDescription, seperti yang ditampilkan pada 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 ke 15:47.

Menggunakan tindakan aksesibilitas

Layanan aksesibilitas dapat mengambil tindakan atas nama pengguna agar interaksi dengan aplikasi menjadi jauh lebih mudah dan lebih produktif. Kemampuan layanan aksesibilitas untuk melakukan tindakan telah ditambahkan di Android 4.0 (API Level 14) dan diperluas secara signifikan di 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 menetapkan android:canRetrieveWindowContent ke true dalam file konfigurasi layanan. Setelah peristiwa diterima oleh layanan, 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 bernavigasi ke layar Utama, menekan tombol Kembali, membuka layar notifikasi, atau mendaftarkan aplikasi terbaru, maka 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 dan menindaklanjutinya. Jenis fokus ini berbeda dengan Fokus Input yang lebih umum, yang menentukan mana elemen antarmuka pengguna di layar yang menerima input 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 apakah elemen tersebut dapat difokuskan input dari perspektif sistem atau tidak. Anda dapat melihat cara kerja fokus aksesibilitas dengan menguji gestur aksesibilitas. Untuk informasi selengkapnya tentang menguji 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 beberapa tindakan dilakukan.

Layanan aksesibilitas dapat menentukan elemen antarmuka pengguna mana yang memiliki Fokus Input atau Fokus Aksesibilitas yang menggunakan metode AccessibilityNodeInfo.findFocus(). Anda juga dapat menelusuri elemen yang dapat dipilih dengan Fokus Input menggunakan metode focusSearch(). Terakhir, layanan aksesibilitas Anda dapat menetapkan 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 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, yang menawarkan informasi kontekstual terbatas. Dalam banyak kasus, informasi konteks yang hilang ini mungkin penting untuk memahami arti kontrol yang dipilih.

Contoh antarmuka yang konteksnya 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 dalam sebulan, 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 dapat diakses oleh layanan aksesibilitas mengenai 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, yang memungkinkan layanan aksesibilitas untuk 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 deskriptif, dan detail lainnya. Mulai Android 4.0 (dan didukung di rilis sebelumnya melalui objek AccessibilityEventCompat dalam Support Library), Anda dapat memperoleh informasi tambahan tentang acara 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 menampilkan objek AccessibilityNodeInfo. Objek ini memungkinkan Anda untuk meminta hierarki tata letak tampilan (induk dan turunan) dari komponen yang berasal dari peristiwa aksesibilitas. Fitur ini memungkinkan layanan aksesibilitas untuk menyelidiki konteks sepenuhnya dari peristiwa, termasuk konten dan status dari tampilan yang disertakan atau tampilan turunan.

    Penting: Kemampuan untuk menyelidiki hierarki tampilan dari AccessibilityEvent dapat berpotensi memperlihatkan informasi pengguna pribadi ke layanan aksesibilitas Anda. Untuk alasan tersebut, layanan Anda harus meminta level akses ini melalui aksesibilitas file XML konfigurasi layanan, dengan menyertakan atribut canRetrieveWindowContent dan menetapkannya ke true. Jika Anda tidak menyertakan penetapan 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 menanggapi tindakan pengguna). Jika layanan Anda memerlukan semua tampilan, layanan dapat meminta tampilan tersebut dengan menetapkan 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 untuk melacak update jendela saat aplikasi menggambar ulang beberapa jendela secara bersamaan. Saat peristiwa TYPE_WINDOWS_CHANGED terjadi, gunakan getWindowChanges() API untuk menentukan bagaimana jendela berubah. Selama update multi-aplikasi, setiap jendela menghasilkan sekumpulan peristiwanya sendiri. Metode getSource() menampilkan tampilan root jendela yang terkait dengan setiap peristiwa.

Jika aplikasi telah mendefinisikan judul panel aksesibilitas untuk objek View-nya, layanan Anda dapat mengenali kapan UI aplikasi diupdate. 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 mengajukan kueri hierarki tampilan, mengumpulkan informasi tentang komponen UI yang menghasilkan peristiwa, serta induk dan turunannya. Untuk melakukannya, pastikan Anda menetapkan baris berikut ke 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. Panggil segera induk tampilan dari tempat peristiwa berasal
  2. Dalam tampilan tersebut, cari label dan kotak centang sebagai turunan tampilan
  3. Jika menemukannya, buat string untuk dilaporkan kepada pengguna, yang menunjukkan label dan apakah label tersebut telah dicentang atau tidak.
  4. Jika nilai null ditampilkan pada tahap mana pun 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);
    }
    

Sekarang, 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 memudahkan 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 di dalam UI aplikasi. Gunakan getTooltipText() untuk membaca teks dari tooltip, dan gunakan ACTION_SHOW_TOOLTIP dan ACTION_HIDE_TOOLTIP untuk menginstruksikan instance View guna menampilkan atau menyembunyikan keterangan tooltip.

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 menetapkan, secara berurutan, apakah konten teks node saat ini mewakili 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 terlihat dalam widget TextView. Layanan 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 mewakili kotak pembatas dari 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(), perhatikan 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 lainnya

Untuk mempelajari lebih lanjut, manfaatkan referensi berikut:

Codelab