سرویس دسترسی خود را ایجاد کنید

سرویس دسترس‌پذیری برنامه‌ای است که رابط کاربری را برای کمک به کاربران دارای معلولیت یا افرادی که ممکن است موقتاً قادر به تعامل کامل با یک دستگاه نباشند، بهبود می‌بخشد. به عنوان مثال، کاربرانی که در حال رانندگی، مراقبت از یک کودک خردسال یا شرکت در یک مهمانی با صدای بلند هستند، ممکن است به بازخورد رابط اضافی یا جایگزین نیاز داشته باشند.

Android خدمات دسترس‌پذیری استاندارد از جمله TalkBack را ارائه می‌کند و توسعه‌دهندگان می‌توانند خدمات خود را ایجاد و توزیع کنند. این سند اصول ساخت یک سرویس دسترسی را توضیح می دهد.

یک سرویس دسترسی را می توان با یک برنامه معمولی همراه کرد یا به عنوان یک پروژه مستقل Android ایجاد کرد. مراحل ایجاد سرویس در هر دو حالت یکسان است.

سرویس دسترسی خود را ایجاد کنید

در پروژه خود، کلاسی ایجاد کنید که AccessibilityService گسترش دهد:

کاتلین

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?) {}
...
}

جاوا

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

...
}

اگر پروژه جدیدی برای این Service ایجاد می‌کنید و قصد ندارید برنامه‌ای مرتبط با آن داشته باشید، می‌توانید کلاس Activity شروع را از منبع خود حذف کنید.

اعلامیه ها و مجوزهای آشکار

برنامه‌هایی که خدمات دسترس‌پذیری ارائه می‌کنند باید اعلان‌های خاصی را در مانیفست‌های برنامه‌شان درج کنند تا توسط سیستم Android به‌عنوان یک سرویس دسترس‌پذیری تلقی شوند. این بخش تنظیمات مورد نیاز و اختیاری را برای خدمات دسترس‌پذیری توضیح می‌دهد.

اعلامیه خدمات دسترسی

برای اینکه برنامه شما به عنوان یک سرویس دسترس‌پذیری در نظر گرفته شود، یک عنصر service - به جای عنصر activity - در عنصر application در مانیفست خود قرار دهید. علاوه بر این، در عنصر service ، یک فیلتر هدف سرویس دسترس‌پذیری را شامل شود. مانیفست همچنین باید با افزودن مجوز BIND_ACCESSIBILITY_SERVICE از سرویس محافظت کند تا اطمینان حاصل شود که فقط سیستم می تواند به آن متصل شود. در اینجا یک مثال است:

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

پیکربندی سرویس دسترسی

سرویس‌های دسترس‌پذیری باید پیکربندی را ارائه دهند که انواع رویدادهای دسترس‌پذیری را که سرویس مدیریت می‌کند و اطلاعات اضافی درباره سرویس را مشخص کند. پیکربندی یک سرویس دسترسی در کلاس AccessibilityServiceInfo موجود است. سرویس شما می تواند با استفاده از نمونه ای از این کلاس و setServiceInfo() در زمان اجرا یک پیکربندی بسازد و تنظیم کند. با این حال، همه گزینه های پیکربندی با استفاده از این روش در دسترس نیستند.

می‌توانید یک عنصر <meta-data> را در مانیفست خود با ارجاع به یک فایل پیکربندی اضافه کنید، که به شما امکان می‌دهد طیف کاملی از گزینه‌ها را برای سرویس دسترسی خود تنظیم کنید، همانطور که در مثال زیر نشان داده شده است:

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

این عنصر <meta-data> به یک فایل XML اشاره دارد که در فهرست منابع برنامه خود ایجاد می‌کنید: <project_dir>/res/xml/accessibility_service_config.xml> . کد زیر نمونه ای از محتویات فایل پیکربندی سرویس را نشان می دهد:

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

برای اطلاعات بیشتر در مورد ویژگی‌های XML که می‌توانند در فایل پیکربندی سرویس دسترس‌پذیری استفاده شوند، به مستندات مرجع زیر مراجعه کنید:

برای اطلاعات بیشتر در مورد اینکه کدام تنظیمات پیکربندی را می توان به صورت پویا در زمان اجرا تنظیم کرد، به مستندات مرجع AccessibilityServiceInfo مراجعه کنید.

سرویس دسترسی خود را پیکربندی کنید

هنگام تنظیم متغیرهای پیکربندی برای سرویس دسترسی خود به موارد زیر توجه کنید تا به سیستم بگویید چگونه و چه زمانی اجرا شود:

  • می‌خواهید به کدام نوع رویداد پاسخ دهد؟
  • آیا این سرویس باید برای همه برنامه ها فعال باشد یا فقط نام بسته های خاص؟
  • از چه نوع بازخوردهای مختلفی استفاده می کند؟

شما دو گزینه برای تنظیم این متغیرها دارید. گزینه سازگار با عقب این است که آنها را در کد تنظیم کنید، با استفاده از setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo) برای انجام این کار، روش onServiceConnected() را لغو کنید و سرویس خود را در آنجا پیکربندی کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

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

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

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

        // Default services are invoked only if no package-specific services are
        // present for the type of AccessibilityEvent generated. This service is
        // app-specific, so the flag isn't necessary. For a general-purpose
        // service, consider setting the DEFAULT flag.

        // flags = AccessibilityServiceInfo.DEFAULT;

        notificationTimeout = 100
    }

    this.serviceInfo = info

}

جاوا

@Override
public void onServiceConnected() {
    // Set the type of events that this service wants to listen to. Others
    // aren't passed to this service.
    info.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED |
            AccessibilityEvent.TYPE_VIEW_FOCUSED;

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

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

    // Default services are invoked only if no package-specific services are
    // present for the type of AccessibilityEvent generated. This service is
    // app-specific, so the flag isn't necessary. For a general-purpose service,
    // consider setting the DEFAULT flag.

    // info.flags = AccessibilityServiceInfo.DEFAULT;

    info.notificationTimeout = 100;

    this.setServiceInfo(info);

}

گزینه دوم این است که سرویس را با استفاده از یک فایل XML پیکربندی کنید. برخی از گزینه‌های پیکربندی، مانند canRetrieveWindowContent ، تنها در صورتی در دسترس هستند که سرویس خود را با استفاده از XML پیکربندی کنید. هنگامی که با استفاده از XML تعریف می شود، گزینه های پیکربندی از مثال قبلی به این صورت است:

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

اگر از XML استفاده می کنید، با افزودن یک تگ <meta-data> به اعلان سرویس خود که به فایل XML اشاره می کند، آن را در مانیفست خود ارجاع دهید. اگر فایل XML خود را در res/xml/serviceconfig.xml ذخیره کنید، تگ جدید به شکل زیر است:

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

روش های خدمات دسترسی

یک سرویس دسترس‌پذیری باید کلاس AccessibilityService را گسترش دهد و روش‌های زیر را از آن کلاس لغو کند. این روش‌ها به ترتیبی که سیستم اندروید آنها را فراخوانی می‌کند ارائه می‌شوند: از زمانی که سرویس شروع می‌شود ( onServiceConnected() )، تا زمانی که در حال اجرا است ( onAccessibilityEvent() ، onInterrupt() )، تا زمانی که آن را خاموش می‌کند ( onUnbind() ).

  • onServiceConnected() : (اختیاری) سیستم زمانی که به سرویس دسترسی شما متصل می شود این روش را فراخوانی می کند. از این روش برای انجام مراحل راه اندازی یکباره سرویس خود، از جمله اتصال به خدمات سیستم بازخورد کاربر، مانند مدیر صدا یا لرزاننده دستگاه، استفاده کنید. اگر می خواهید پیکربندی سرویس خود را در زمان اجرا تنظیم کنید یا تنظیمات یکباره انجام دهید، این مکان مناسبی برای فراخوانی setServiceInfo() است.

  • onAccessibilityEvent() : (الزامی) هنگامی که سیستم AccessibilityEvent شناسایی می کند که با پارامترهای فیلتر رویداد مشخص شده توسط سرویس دسترس پذیری شما مطابقت دارد، این روش را دوباره فراخوانی می کند، مانند زمانی که کاربر روی دکمه ای ضربه می زند یا روی یک کنترل رابط کاربری در یک برنامه در دسترس بودن شما تمرکز می کند. خدمات ارائه بازخورد برای. هنگامی که سیستم این روش را فراخوانی می‌کند، AccessibilityEvent مرتبط را ارسال می‌کند، که سپس سرویس می‌تواند آن را تفسیر کرده و برای ارائه بازخورد به کاربر استفاده کند. این روش را می توان بارها در طول چرخه عمر سرویس شما فراخوانی کرد.

  • onInterrupt() : (لازم) سیستم زمانی این روش را فراخوانی می‌کند که سیستم می‌خواهد بازخوردی را که سرویس شما ارائه می‌کند قطع کند، معمولاً در پاسخ به یک اقدام کاربر مانند انتقال تمرکز به یک کنترل دیگر. این روش را می توان بارها در طول چرخه عمر سرویس شما فراخوانی کرد.

  • onUnbind() : (اختیاری) هنگامی که سیستم در شرف خاموش کردن سرویس دسترسی است، سیستم این متد را فراخوانی می کند. از این روش برای انجام هر گونه روش خاموش کردن یکباره، از جمله عدم تخصیص خدمات سیستم بازخورد کاربر، مانند مدیر صدا یا ویبراتور دستگاه استفاده کنید.

این روش‌های پاسخ به تماس ساختار اولیه سرویس دسترسی شما را فراهم می‌کنند. شما می توانید تصمیم بگیرید که چگونه داده های ارائه شده توسط سیستم Android را در قالب اشیاء AccessibilityEvent پردازش کنید و به کاربر بازخورد ارائه دهید. برای اطلاعات بیشتر درباره دریافت اطلاعات از یک رویداد دسترس‌پذیری، به دریافت جزئیات رویداد مراجعه کنید.

برای رویدادهای دسترسی ثبت نام کنید

یکی از مهم‌ترین عملکردهای پارامترهای پیکربندی سرویس دسترس‌پذیری این است که به شما امکان می‌دهد نوع رویدادهای دسترس‌پذیری را مشخص کنید که سرویس شما می‌تواند مدیریت کند. مشخص کردن این اطلاعات به سرویس‌های دسترس‌پذیری اجازه می‌دهد با یکدیگر همکاری کنند و به شما این امکان را می‌دهد که فقط انواع رویدادهای خاص را از برنامه‌های خاص مدیریت کنید. فیلتر رویداد می تواند شامل معیارهای زیر باشد:

  • نام‌های بسته: نام بسته‌های برنامه‌هایی را که می‌خواهید سرویس شما به رویدادهای دسترسی آنها رسیدگی کند، مشخص کنید. اگر این پارامتر حذف شود، سرویس دسترس‌پذیری شما در دسترس رویدادهای دسترس‌پذیری سرویس برای هر برنامه در نظر گرفته می‌شود. می‌توانید این پارامتر را در فایل‌های پیکربندی سرویس دسترس‌پذیری با ویژگی android:packageNames به‌عنوان فهرستی جدا شده با کاما تنظیم کنید یا از عضو AccessibilityServiceInfo.packageNames استفاده کنید.

  • انواع رویداد: انواع رویدادهای دسترس‌پذیری را که می‌خواهید سرویس شما مدیریت کند، مشخص کنید. می‌توانید این پارامتر را در فایل‌های پیکربندی سرویس دسترسی با ویژگی android:accessibilityEventTypes به‌عنوان فهرستی که با | کاراکتر—برای مثال، accessibilityEventTypes="typeViewClicked|typeViewFocused" . یا می توانید آن را با استفاده از عضو AccessibilityServiceInfo.eventTypes تنظیم کنید.

هنگام تنظیم سرویس دسترسی خود، به دقت در نظر بگیرید که سرویس شما چه رویدادهایی را می تواند انجام دهد و فقط برای آن رویدادها ثبت نام کنید. از آنجایی که کاربران می‌توانند همزمان بیش از یک سرویس دسترس‌پذیری را فعال کنند، سرویس شما نباید رویدادهایی را مصرف کند که قادر به مدیریت آنها نیست. به یاد داشته باشید که سایر خدمات ممکن است این رویدادها را برای بهبود تجربه کاربر مدیریت کنند.

حجم دسترسی

دستگاه‌هایی که دارای Android 8.0 (سطح API 26) و بالاتر هستند شامل دسته صدای STREAM_ACCESSIBILITY هستند که به شما امکان می‌دهد میزان صدای خروجی صدای سرویس دسترس‌پذیری خود را مستقل از سایر صداهای دستگاه کنترل کنید.

خدمات دسترس‌پذیری می‌توانند با تنظیم گزینه FLAG_ENABLE_ACCESSIBILITY_VOLUME از این نوع جریان استفاده کنند. سپس می‌توانید میزان صدای دسترسی دستگاه را با فراخوانی متد adjustStreamVolume() در نمونه AudioManager دستگاه تغییر دهید.

قطعه کد زیر نشان می‌دهد که چگونه یک سرویس دسترس‌پذیری می‌تواند از دسته حجم STREAM_ACCESSIBILITY استفاده کند:

کاتلین

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

جاوا

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

برای اطلاعات بیشتر، ویدیوی جلسه قابلیت دسترسی اندروید چه جدید است از Google I/O 2017، از ساعت 6:35 شروع می‌شود را ببینید.

میانبر دسترسی

در دستگاه‌های دارای Android 8.0 (سطح API 26) و بالاتر، کاربران می‌توانند با فشار دادن و نگه داشتن همزمان هر دو کلید میزان صدا، سرویس دسترس‌پذیری مورد نظر خود را از هر صفحه‌ای فعال و غیرفعال کنند. اگرچه این میانبر Talkback را به طور پیش‌فرض فعال و غیرفعال می‌کند، کاربران می‌توانند دکمه را برای فعال و غیرفعال کردن هر سرویسی که روی دستگاهشان نصب شده است، پیکربندی کنند.

برای اینکه کاربران از میانبر دسترس‌پذیری به یک سرویس دسترس‌پذیری خاص دسترسی پیدا کنند، سرویس باید این ویژگی را در زمان اجرا درخواست کند.

برای اطلاعات بیشتر، ویدیوی جلسه قابلیت دسترسی اندروید چه جدید است از Google I/O 2017، از ساعت 13:25 شروع می شود را ببینید.

دکمه دسترسی

در دستگاه‌هایی که از ناحیه پیمایش ارائه‌شده توسط نرم‌افزار استفاده می‌کنند و دارای Android 8.0 (سطح API 26) یا بالاتر هستند، سمت راست نوار پیمایش شامل یک دکمه دسترسی است. هنگامی که کاربران این دکمه را فشار می دهند، بسته به محتوایی که در حال حاضر روی صفحه نمایش داده می شود، می توانند یکی از چندین ویژگی و سرویس دسترسی فعال را فراخوانی کنند.

برای اینکه به کاربران اجازه دهد با استفاده از دکمه دسترس‌پذیری، سرویس دسترس‌پذیری معین را فراخوانی کنند، این سرویس باید پرچم FLAG_REQUEST_ACCESSIBILITY_BUTTON را در ویژگی android:accessibilityFlags شی AccessibilityServiceInfo اضافه کند. سپس این سرویس می تواند با استفاده از registerAccessibilityButtonCallback() تماس های برگشتی را ثبت کند.

قطعه کد زیر نشان می دهد که چگونه می توانید یک سرویس دسترس پذیری را پیکربندی کنید تا به کاربر با فشار دادن دکمه دسترسی پاسخ دهد:

کاتلین

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

جاوا

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

برای اطلاعات بیشتر، ویدیوی جلسه قابلیت دسترسی اندروید چه جدید است از Google I/O 2017، از ساعت 16:28 شروع می‌شود را ببینید.

حرکات اثر انگشت

سرویس‌های دسترس‌پذیری در دستگاه‌های دارای Android 8.0 (سطح API 26) یا بالاتر می‌توانند به تند کشیدن‌های جهت‌دار (بالا، پایین، چپ و راست) در امتداد حسگر اثر انگشت دستگاه پاسخ دهند. برای پیکربندی یک سرویس برای دریافت پاسخ تماس در مورد این تعاملات، دنباله زیر را تکمیل کنید:

  1. مجوز USE_BIOMETRIC و قابلیت CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES را اعلام کنید.
  2. پرچم FLAG_REQUEST_FINGERPRINT_GESTURES را در ویژگی android:accessibilityFlags تنظیم کنید.
  3. با استفاده از registerFingerprintGestureCallback() برای تماس های برگشتی ثبت نام کنید.

به خاطر داشته باشید که همه دستگاه ها دارای حسگر اثر انگشت نیستند. برای تشخیص اینکه آیا یک دستگاه از سنسور پشتیبانی می کند یا خیر، از روش isHardwareDetected() استفاده کنید. حتی در دستگاهی که دارای حسگر اثر انگشت است، سرویس شما نمی‌تواند از سنسور زمانی که برای اهداف احراز هویت استفاده می‌شود استفاده کند. برای شناسایی زمانی که حسگر در دسترس است، متد isGestureDetectionAvailable() را فراخوانی کنید و پاسخ تماس onGestureDetectionAvailabilityChanged() را اجرا کنید.

قطعه کد زیر نمونه ای از استفاده از ژست های اثر انگشت را برای حرکت در صفحه بازی مجازی نشان می دهد:

// 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.kt
import android.accessibilityservice.FingerprintGestureController.*

class MyFingerprintGestureService : AccessibilityService() {

    private var gestureController: FingerprintGestureController? = null
    private var fingerprintGestureCallback:
            FingerprintGestureController.FingerprintGestureCallback? = null
    private var mIsGestureDetectionAvailable: Boolean = false

    override fun onCreate() {
        gestureController = fingerprintGestureController
        mIsGestureDetectionAvailable = gestureController?.isGestureDetectionAvailable ?: false
    }

    override fun onServiceConnected() {
        if (mFingerprintGestureCallback != null || !mIsGestureDetectionAvailable) return

        fingerprintGestureCallback =
                object : FingerprintGestureController.FingerprintGestureCallback() {
                    override fun onGestureDetected(gesture: Int) {
                        when (gesture) {
                            FINGERPRINT_GESTURE_SWIPE_DOWN -> moveGameCursorDown()
                            FINGERPRINT_GESTURE_SWIPE_LEFT -> moveGameCursorLeft()
                            FINGERPRINT_GESTURE_SWIPE_RIGHT -> moveGameCursorRight()
                            FINGERPRINT_GESTURE_SWIPE_UP -> moveGameCursorUp()
                            else -> Log.e(MY_APP_TAG, "Error: Unknown gesture type detected!")
                        }
                    }

                    override fun onGestureDetectionAvailabilityChanged(available: Boolean) {
                        mIsGestureDetectionAvailable = available
                    }
                }

        fingerprintGestureCallback?.also {
            gestureController?.registerFingerprintGestureCallback(it, null)
        }
    }
}

جاوا

// MyFingerprintGestureService.java
import static android.accessibilityservice.FingerprintGestureController.*;

public class MyFingerprintGestureService extends AccessibilityService {
    private FingerprintGestureController gestureController;
    private FingerprintGestureController
            .FingerprintGestureCallback fingerprintGestureCallback;
    private boolean mIsGestureDetectionAvailable;

    @Override
    public void onCreate() {
        gestureController = getFingerprintGestureController();
        mIsGestureDetectionAvailable =
                gestureController.isGestureDetectionAvailable();
    }

    @Override
    protected void onServiceConnected() {
        if (fingerprintGestureCallback != null
                || !mIsGestureDetectionAvailable) {
            return;
        }

        fingerprintGestureCallback =
               new FingerprintGestureController.FingerprintGestureCallback() {
            @Override
            public void onGestureDetected(int gesture) {
                switch (gesture) {
                    case FINGERPRINT_GESTURE_SWIPE_DOWN:
                        moveGameCursorDown();
                        break;
                    case FINGERPRINT_GESTURE_SWIPE_LEFT:
                        moveGameCursorLeft();
                        break;
                    case FINGERPRINT_GESTURE_SWIPE_RIGHT:
                        moveGameCursorRight();
                        break;
                    case FINGERPRINT_GESTURE_SWIPE_UP:
                        moveGameCursorUp();
                        break;
                    default:
                        Log.e(MY_APP_TAG,
                                  "Error: Unknown gesture type detected!");
                        break;
                }
            }

            @Override
            public void onGestureDetectionAvailabilityChanged(boolean available) {
                mIsGestureDetectionAvailable = available;
            }
        };

        if (fingerprintGestureCallback != null) {
            gestureController.registerFingerprintGestureCallback(
                    fingerprintGestureCallback, null);
        }
    }
}

برای اطلاعات بیشتر، ویدیوی جلسه قابلیت دسترسی اندروید چه جدید است از Google I/O 2017، از ساعت 9:03 شروع می‌شود را ببینید.

متن به گفتار چند زبانه

با شروع از Android 8.0 (سطح API 26)، سرویس متن به گفتار (TTS) Android می‌تواند عبارات را به چندین زبان در یک بلوک متن شناسایی و بیان کند. برای فعال کردن این قابلیت تغییر خودکار زبان در یک سرویس دسترس‌پذیری، تمام رشته‌ها را در اشیاء LocaleSpan بپیچید، همانطور که در قطعه کد زیر نشان داده شده است:

کاتلین

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

جاوا

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

برای اطلاعات بیشتر، ویدیوی جلسه قابلیت دسترسی اندروید چه جدید است را از Google I/O 2017 از ساعت 10:59 شروع کنید.

از طرف کاربران اقدام کنید

از سال 2011، خدمات دسترس‌پذیری می‌توانند از طرف کاربران، از جمله تغییر تمرکز ورودی و انتخاب (فعال‌سازی) عناصر رابط کاربر، عمل کنند. در سال 2012، دامنه اقدامات گسترش یافت و شامل لیست های پیمایش و تعامل با فیلدهای متنی شد. سرویس‌های دسترس‌پذیری همچنین می‌توانند اقدامات سراسری، مانند پیمایش به صفحه اصلی، فشار دادن دکمه برگشت، و باز کردن صفحه اعلان‌ها و لیست برنامه‌های اخیر انجام دهند. از سال 2012، Android شامل تمرکز دسترس‌پذیری است که همه عناصر قابل مشاهده را توسط یک سرویس دسترس‌پذیری قابل انتخاب می‌کند.

این قابلیت‌ها به توسعه‌دهندگان سرویس‌های دسترس‌پذیری اجازه می‌دهد حالت‌های ناوبری جایگزین، مانند ناوبری اشاره‌ای، ایجاد کنند و به کاربران دارای معلولیت، کنترل بهتری بر دستگاه‌های مجهز به Android خود ارائه دهند.

برای ژست ها گوش دهید

سرویس‌های دسترس‌پذیری می‌توانند به حرکات خاصی گوش دهند و با اقدام از طرف یک کاربر پاسخ دهند. این ویژگی مستلزم آن است که سرویس دسترس‌پذیری شما درخواست فعال‌سازی ویژگی کاوش با لمس کند. سرویس شما می‌تواند با تنظیم flags عضو نمونه AccessibilityServiceInfo روی FLAG_REQUEST_TOUCH_EXPLORATION_MODE ، این فعال‌سازی را درخواست کند، همانطور که در مثال زیر نشان داده شده است.

کاتلین

class MyAccessibilityService : AccessibilityService() {

    override fun onCreate() {
        serviceInfo.flags = AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE
    }
    ...
}

جاوا

public class MyAccessibilityService extends AccessibilityService {
    @Override
    public void onCreate() {
        getServiceInfo().flags = AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
    }
    ...
}

پس از درخواست سرویس شما برای فعال‌سازی کاوش با لمس، کاربر باید اجازه دهد این ویژگی فعال شود، اگر قبلاً فعال نیست. هنگامی که این ویژگی فعال است، سرویس شما اعلان حرکات دسترسی را از طریق روش پاسخ به تماس onGesture() سرویس شما دریافت می‌کند و می‌تواند با اقدام از طرف کاربر پاسخ دهد.

ادامه ژست ها

دستگاه‌های دارای Android 8.0 (سطح API 26) از حرکات مداوم یا حرکات برنامه‌ای حاوی بیش از یک شی Path پشتیبانی می‌کنند.

هنگام تعیین دنباله ای از strokes ها، می توانید با استفاده از آرگومان نهایی willContinue در سازنده GestureDescription.StrokeDescription مشخص کنید که آنها به همان حرکت برنامه ای تعلق دارند، همانطور که در قطعه کد زیر نشان داده شده است:

کاتلین

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

جاوا

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

برای اطلاعات بیشتر، ویدیوی جلسه قابلیت دسترسی اندروید چه جدید است را از Google I/O 2017 از ساعت 15:47 شروع کنید.

از اقدامات دسترسی استفاده کنید

خدمات دسترس‌پذیری می‌توانند از طرف کاربران برای ساده‌سازی تعامل با برنامه‌ها و بهره‌وری بیشتر عمل کنند. توانایی خدمات دسترسی برای انجام اقدامات در سال 2011 اضافه شد و در سال 2012 به طور قابل توجهی گسترش یافت.

برای اقدام از طرف کاربران، سرویس دسترسی شما باید ثبت نام کند تا رویدادها را از برنامه ها دریافت کند و با تنظیم android:canRetrieveWindowContent روی true در فایل پیکربندی سرویس، مجوز برای مشاهده محتوای برنامه ها درخواست کند. هنگامی که رویدادها توسط سرویس شما دریافت می شود، سپس می تواند شی AccessibilityNodeInfo را با استفاده از getSource() از رویداد بازیابی کند. با شی AccessibilityNodeInfo ، سرویس شما می‌تواند سلسله‌مراتب view را بررسی کند تا مشخص کند چه اقدامی باید انجام دهد و سپس با استفاده از performAction() برای کاربر عمل کند.

کاتلین

class MyAccessibilityService : AccessibilityService() {

    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        // Get the source node of the event.
        event.source?.apply {

            // Use the event and node information to determine what action to
            // take.

            // Act on behalf of the user.
            performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)

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

جاوا

public class MyAccessibilityService extends AccessibilityService {

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        // Get the source node of the event.
        AccessibilityNodeInfo nodeInfo = event.getSource();

        // Use the event and node information to determine what action to take.

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

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

متد performAction() به سرویس شما اجازه می دهد تا در یک برنامه اقدام کند. اگر سرویس شما نیاز به انجام یک عمل سراسری، مانند پیمایش به صفحه اصلی، ضربه زدن روی دکمه برگشت، یا باز کردن صفحه اعلان‌ها یا لیست برنامه‌های اخیر دارد، از روش performGlobalAction() استفاده کنید.

از انواع فوکوس استفاده کنید

در سال 2012، اندروید یک تمرکز رابط کاربری به نام تمرکز دسترسی را معرفی کرد. سرویس‌های دسترس‌پذیری می‌توانند از این تمرکز برای انتخاب هر عنصر رابط کاربری قابل مشاهده و عمل بر روی آن استفاده کنند. این نوع فوکوس با فوکوس ورودی متفاوت است، که تعیین می‌کند وقتی کاربر نویسه‌ها را تایپ می‌کند، Enter را روی صفحه‌کلید فشار می‌دهد یا دکمه مرکزی یک D-pad را فشار می‌دهد، کدام عنصر رابط کاربری روی صفحه ورودی دریافت می‌کند.

این امکان وجود دارد که یک عنصر در رابط کاربری دارای فوکوس ورودی باشد در حالی که عنصر دیگر دارای تمرکز دسترسی باشد. هدف از تمرکز دسترسی، ارائه خدمات دسترسی با روشی برای تعامل با عناصر قابل مشاهده بر روی صفحه نمایش است، صرف نظر از اینکه آیا عنصر از دیدگاه سیستم قابل تمرکز بر ورودی است یا خیر. برای اطمینان از اینکه سرویس دسترس‌پذیری شما به‌درستی با عناصر ورودی برنامه‌ها تعامل دارد، دستورالعمل‌های آزمایش دسترس‌پذیری برنامه را دنبال کنید تا سرویس خود را هنگام استفاده از یک برنامه معمولی آزمایش کنید.

یک سرویس دسترس‌پذیری می‌تواند با استفاده از روش AccessibilityNodeInfo.findFocus() تعیین کند که کدام عنصر رابط کاربری دارای فوکوس ورودی یا تمرکز دسترسی است. همچنین می توانید با استفاده از متد focusSearch() عناصری را جستجو کنید که می توانند با فوکوس ورودی انتخاب شوند. در نهایت، سرویس دسترس‌پذیری شما می‌تواند با استفاده از روش performAction(AccessibilityNodeInfo.ACTION_SET_ACCESSIBILITY_FOCUS) تمرکز دسترسی را تنظیم کند.

اطلاعات جمع آوری کنید

سرویس‌های دسترس‌پذیری روش‌های استانداردی برای جمع‌آوری و نمایش واحدهای کلیدی اطلاعات ارائه‌شده توسط کاربر، مانند جزئیات رویداد، متن و اعداد دارند.

دریافت جزئیات تغییر پنجره

Android 9 (سطح API 28) و بالاتر به برنامه‌ها اجازه می‌دهد به‌روزرسانی‌های پنجره‌ها را هنگامی که یک برنامه چندین پنجره را به‌طور همزمان دوباره ترسیم می‌کند، پیگیری کنند. هنگامی که یک رویداد TYPE_WINDOWS_CHANGED رخ می دهد، از getWindowChanges() API برای تعیین نحوه تغییر ویندوز استفاده کنید. در طول یک به روز رسانی چند پنجره ای، هر پنجره مجموعه ای از رویدادها را تولید می کند. متد getSource() نمای ریشه پنجره مرتبط با هر رویداد را برمی گرداند.

اگر برنامه‌ای عناوین صفحه دسترس‌پذیری را برای اشیاء View خود تعریف کند، سرویس شما می‌تواند تشخیص دهد که چه زمانی رابط کاربری برنامه به‌روزرسانی می‌شود. هنگامی که یک رویداد TYPE_WINDOW_STATE_CHANGED رخ می دهد، از انواع برگردانده شده توسط getContentChangeTypes() برای تعیین نحوه تغییر پنجره استفاده کنید. به عنوان مثال، فریم ورک می تواند تشخیص دهد که یک صفحه عنوان جدیدی دارد یا زمانی که یک صفحه ناپدید می شود.

جزئیات رویداد را دریافت کنید

Android اطلاعاتی را در مورد تعامل رابط کاربری از طریق اشیاء AccessibilityEvent در اختیار سرویس‌های دسترس‌پذیری قرار می‌دهد. در نسخه‌های قبلی اندروید، اطلاعات موجود در یک رویداد دسترس‌پذیری، در حالی که جزئیات قابل توجهی در مورد کنترل رابط کاربری انتخاب شده توسط کاربران ارائه می‌دهد، اطلاعات متنی محدودی را ارائه می‌دهد. در بسیاری از موارد، این اطلاعات زمینه از دست رفته ممکن است برای درک معنای کنترل انتخاب شده حیاتی باشد.

نمونه‌ای از یک رابط که در آن زمینه حیاتی است، یک تقویم یا برنامه‌ریز روز است. اگر کاربر در لیست روزهای دوشنبه تا جمعه، یک بازه زمانی 4 بعد از ظهر را انتخاب کند و سرویس دسترس‌پذیری «4 بعد از ظهر» را اعلام کند، اما نام روز هفته، روز ماه یا نام ماه را اعلام نکند، نتیجه می‌شود. بازخورد گیج کننده است در این مورد، زمینه کنترل رابط کاربری برای کاربری که می‌خواهد یک جلسه را برنامه‌ریزی کند، حیاتی است.

از سال 2011، Android به طور قابل توجهی مقدار اطلاعاتی را که یک سرویس دسترس‌پذیری می‌تواند در مورد تعامل رابط کاربری به دست آورد، با ایجاد رویدادهای دسترس‌پذیری بر اساس سلسله‌مراتب مشاهده گسترش داده است. سلسله مراتب نمای مجموعه ای از مؤلفه های رابط کاربری است که شامل مؤلفه (والدین آن) و عناصر رابط کاربری است که ممکن است توسط آن مؤلفه (فرزندان) موجود باشد. به این ترتیب، Android می‌تواند جزئیات غنی‌تری در مورد رویدادهای دسترس‌پذیری ارائه دهد و به خدمات دسترس‌پذیری اجازه می‌دهد بازخورد مفیدتری را به کاربران ارائه دهند.

یک سرویس دسترس‌پذیری اطلاعات مربوط به یک رویداد رابط کاربر را از طریق AccessibilityEvent که توسط سیستم به روش پاسخ تماس onAccessibilityEvent() ارسال می‌شود، دریافت می‌کند. این شی جزئیات مربوط به رویداد را ارائه می دهد، از جمله نوع شیء مورد عمل، متن توصیفی آن و جزئیات دیگر.

  • AccessibilityEvent.getRecordCount() و getRecord(int) : این روش ها به شما امکان می دهند مجموعه ای از اشیاء AccessibilityRecord را که به AccessibilityEvent ارسال شده توسط سیستم به شما کمک می کنند، بازیابی کنید. این سطح از جزئیات زمینه بیشتری را برای رویدادی که سرویس دسترسی شما را راه اندازی می کند، فراهم می کند.

  • AccessibilityRecord.getSource() : این روش یک شی AccessibilityNodeInfo را برمی گرداند. این شی به شما امکان می‌دهد سلسله‌مراتب طرح‌بندی view (والدین و فرزندان) مؤلفه‌ای که رویداد دسترسی را ایجاد می‌کند، درخواست کنید. این ویژگی به یک سرویس دسترس‌پذیری اجازه می‌دهد تا زمینه کامل یک رویداد، از جمله محتوا و وضعیت هر نماهای محصور یا نماهای کودک را بررسی کند.

پلتفرم Android این امکان را برای AccessibilityService فراهم می‌کند تا سلسله‌مراتب view را جستجو کند و اطلاعات مربوط به مؤلفه UI که یک رویداد را ایجاد می‌کند و همچنین والدین و فرزندان آن جمع‌آوری کند. برای انجام این کار، خط زیر را در پیکربندی XML خود تنظیم کنید:

android:canRetrieveWindowContent="true"

پس از انجام این کار، با استفاده از getSource() یک شی AccessibilityNodeInfo دریافت کنید. این فراخوانی تنها در صورتی یک شی را برمی گرداند که پنجره ای که رویداد از آنجا شروع می شود همچنان پنجره فعال باشد. اگر نه، آن را باطل بر می گرداند، بنابراین مطابق با آن رفتار کنید.

در مثال زیر، کد زمانی که یک رویداد دریافت می‌شود، کارهای زیر را انجام می‌دهد:

  1. فوراً والد منظره ای را می گیرد که رویداد از آنجا منشا گرفته است.
  2. در آن نما، به دنبال یک برچسب و یک چک باکس به عنوان نمایش های کودک است.
  3. اگر آنها را پیدا کرد، یک رشته برای گزارش به کاربر ایجاد می کند که نشان می دهد برچسب و اینکه آیا بررسی شده است یا خیر.

اگر در هر نقطه یک مقدار تهی هنگام عبور از سلسله مراتب view برگردانده شود، روش بی سر و صدا منصرف می شود.

کاتلین

// Alternative onAccessibilityEvent that uses AccessibilityNodeInfo.

override fun onAccessibilityEvent(event: AccessibilityEvent) {

    val source: AccessibilityNodeInfo = event.source ?: return

    // Grab the parent of the view that fires the event.
    val rowNode: AccessibilityNodeInfo = getListItemNodeInfo(source) ?: return

    // Using this parent, get references to both child nodes, the label, and the
    // checkbox.
    val taskLabel: CharSequence = rowNode.getChild(0)?.text ?: run {
        rowNode.recycle()
        return
    }

    val isComplete: Boolean = rowNode.getChild(1)?.isChecked ?: run {
        rowNode.recycle()
        return
    }

    // Determine what the task is and whether it's complete based on the text
    // inside the label, and the state of the checkbox.
    if (rowNode.childCount < 2 || !rowNode.getChild(1).isCheckable) {
        rowNode.recycle()
        return
    }

    val completeStr: String = if (isComplete) {
        getString(R.string.checked)
    } else {
        getString(R.string.not_checked)
    }
    val reportStr = "$taskLabel$completeStr"
    speakToUser(reportStr)
}

جاوا

// Alternative onAccessibilityEvent that uses AccessibilityNodeInfo.

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

    AccessibilityNodeInfo source = event.getSource();
    if (source == null) {
        return;
    }

    // Grab the parent of the view that fires the event.
    AccessibilityNodeInfo rowNode = getListItemNodeInfo(source);
    if (rowNode == null) {
        return;
    }

    // Using this parent, get references to both child nodes, the label, and the
    // checkbox.
    AccessibilityNodeInfo labelNode = rowNode.getChild(0);
    if (labelNode == null) {
        rowNode.recycle();
        return;
    }

    AccessibilityNodeInfo completeNode = rowNode.getChild(1);
    if (completeNode == null) {
        rowNode.recycle();
        return;
    }

    // Determine what the task is and whether it's complete based on the text
    // inside the label, and the state of the checkbox.
    if (rowNode.getChildCount() < 2 || !rowNode.getChild(1).isCheckable()) {
        rowNode.recycle();
        return;
    }

    CharSequence taskLabel = labelNode.getText();
    final boolean isComplete = completeNode.isChecked();
    String completeStr = null;

    if (isComplete) {
        completeStr = getString(R.string.checked);
    } else {
        completeStr = getString(R.string.not_checked);
    }
    String reportStr = taskLabel + completeStr;
    speakToUser(reportStr);
}

اکنون شما یک سرویس دسترسی کامل و کارآمد دارید. با افزودن موتور تبدیل متن به گفتار Android یا استفاده از Vibrator برای ارائه بازخورد لمسی، نحوه تعامل آن با کاربر را پیکربندی کنید.

متن پردازش

دستگاه‌هایی که دارای Android 8.0 (سطح API 26) و بالاتر هستند، دارای چندین ویژگی پردازش متن هستند که شناسایی و عملکرد سرویس‌های دسترس‌پذیری را بر روی واحدهای متن خاصی که روی صفحه نمایش ظاهر می‌شوند، آسان‌تر می‌کنند.

نکات ابزار

اندروید 9 (سطح API 28) چندین قابلیت را معرفی می کند که به شما امکان می دهد به نکات ابزار در رابط کاربری برنامه دسترسی داشته باشید. از getTooltipText() برای خواندن متن یک راهنمای ابزار استفاده کنید و از ACTION_SHOW_TOOLTIP و ACTION_HIDE_TOOLTIP برای دستور دادن به نمونه هایی از View برای نمایش یا پنهان کردن نکات ابزارشان استفاده کنید.

متن اشاره

از سال 2017، اندروید شامل چندین روش برای تعامل با متن اشاره یک شی مبتنی بر متن است:

  • متدهای isShowingHintText() و setShowingHintText() به ترتیب نشان می دهند و تنظیم می کنند که آیا محتوای متن فعلی گره نشان دهنده متن اشاره گره است یا خیر.
  • getHintText() دسترسی به خود متن اشاره را فراهم می کند. حتی اگر یک شی متن راهنمایی را نمایش نمی‌دهد، فراخوانی getHintText() با موفقیت انجام می‌شود.

مکان کاراکترهای متن روی صفحه

در دستگاه‌های دارای Android 8.0 (سطح API 26) و بالاتر، سرویس‌های دسترس‌پذیری می‌توانند مختصات صفحه‌نمایش را برای کادر محدود نویسه‌های قابل مشاهده در ویجت TextView تعیین کنند. سرویس‌ها این مختصات را با فراخوانی refreshWithExtraData() پیدا می‌کنند، و EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY را به عنوان اولین آرگومان و یک شی Bundle به عنوان آرگومان دوم ارسال می‌کنند. همانطور که متد اجرا می شود، سیستم آرگومان Bundle را با یک آرایه parcelable از اشیاء Rect پر می کند. هر شی Rect نمایانگر جعبه مرزی یک کاراکتر خاص است.

مقادیر محدوده یک طرفه استاندارد شده

برخی از اشیاء AccessibilityNodeInfo از نمونه ای از AccessibilityNodeInfo.RangeInfo استفاده می کنند تا نشان دهند که یک عنصر UI می تواند محدوده ای از مقادیر را بگیرد. هنگام ایجاد یک محدوده با استفاده از RangeInfo.obtain() یا هنگام بازیابی مقادیر شدید محدوده با استفاده از getMin() و getMax() ، به خاطر داشته باشید که دستگاه های دارای Android 8.0 (سطح API 26) و بالاتر، محدوده های یک طرفه را در به صورت استاندارد:

  • برای محدوده‌های بدون حداقل، Float.NEGATIVE_INFINITY حداقل مقدار را نشان می‌دهد.
  • برای محدوده‌های بدون حداکثر، Float.POSITIVE_INFINITY حداکثر مقدار را نشان می‌دهد.

به رویدادهای دسترسی پاسخ دهید

اکنون که سرویس شما برای اجرا و گوش دادن به رویدادها تنظیم شده است، کد بنویسید تا بداند هنگام ورود AccessibilityEvent چه کاری انجام دهد. با نادیده گرفتن روش onAccessibilityEvent(AccessibilityEvent) شروع کنید. در آن روش، از getEventType() برای تعیین نوع رویداد و getContentDescription() برای استخراج هر متن برچسب مرتبط با view که رویداد را فعال می کند، استفاده کنید:

کاتلین

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

جاوا

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

منابع اضافی

برای کسب اطلاعات بیشتر به منابع زیر مراجعه کنید:

راهنماها

Codelabs