Erişilebilirlik hizmeti, bir cihazla geçici olarak tam olarak etkileşimde bulunamayan veya engelli kullanıcılara yardımcı olmak için kullanıcı arayüzünü geliştiren bir uygulamadır. Örneğin, araba kullanan, küçük bir çocukla ilgilenen veya çok gürültülü bir partiye katılan kullanıcıların ek ya da alternatif arayüz geri bildirimine ihtiyacı olabilir.
Android, TalkBack gibi standart erişilebilirlik hizmetlerini sağlar. Geliştiriciler kendi hizmetlerini oluşturup dağıtabilir. Bu belgede erişilebilirlik hizmeti oluşturmanın temelleri açıklanmaktadır.
Erişilebilirlik hizmeti normal bir uygulamayla paket haline getirilebilir veya bağımsız bir Android projesi olarak oluşturulabilir. Hizmeti oluşturma adımları her iki durumda da aynıdır.
Erişilebilirlik hizmetinizi oluşturun
Projenizde şu kapsamı genişleten bir sınıf oluşturun:
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() { } ... }
Bu Service
için yeni bir proje oluşturursanız ve bu projeyle ilişkili bir uygulama olmasını planlamıyorsanız başlangıç Activity
sınıfını kaynağınızdan kaldırabilirsiniz.
Manifest beyanları ve izinleri
Erişilebilirlik hizmetleri sağlayan uygulamaların Android sistemi tarafından erişilebilirlik hizmeti olarak değerlendirilebilmesi için bu uygulamaların manifest dosyalarında belirli beyanlar yer alması gerekir. Bu bölümde, erişilebilirlik hizmetleri için gerekli ve isteğe bağlı ayarlar açıklanmaktadır.
Erişilebilirlik hizmeti beyanı
Uygulamanızın erişilebilirlik hizmeti olarak değerlendirilmesi için manifest dosyanızdaki application
öğesine activity
öğesi yerine bir service
öğesi ekleyin. Buna ek olarak, service
öğesine bir erişilebilirlik hizmeti amacı filtresi ekleyin. Manifest ayrıca hizmete yalnızca sistemin bağlanmasını sağlamak için BIND_ACCESSIBILITY_SERVICE
iznini ekleyerek hizmeti korumalıdır. Aşağıda bununla ilgili bir örnek verilmiştir:
<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>
Erişilebilirlik hizmeti yapılandırması
Erişilebilirlik hizmetleri, hizmetin işlediği erişilebilirlik etkinliği türlerini ve hizmetle ilgili ek bilgileri belirten bir yapılandırma sağlamalıdır. Erişilebilirlik hizmetinin yapılandırması, AccessibilityServiceInfo
sınıfında yer alır. Hizmetiniz bu sınıfın bir örneğini ve çalışma zamanında setServiceInfo()
hizmetini kullanarak bir yapılandırma derleyip ayarlayabilir. Ancak bu yöntem kullanılarak tüm yapılandırma seçenekleri kullanılamaz.
Yapılandırma dosyasına referansla manifest dosyanıza bir <meta-data>
öğesi ekleyebilirsiniz. Böylece, aşağıdaki örnekte gösterildiği gibi erişilebilirlik hizmetiniz için tüm seçenekleri ayarlayabilirsiniz:
<service android:name=".MyAccessibilityService"> ... <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config" /> </service>
Bu <meta-data>
öğesi, uygulamanızın kaynak dizininde oluşturduğunuz bir XML dosyasını ifade eder: <project_dir>/res/xml/accessibility_service_config.xml>
. Aşağıdaki kod, hizmet yapılandırma dosyasının içeriğinin bir örneğini gösterir:
<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" />
Erişilebilirlik hizmeti yapılandırma dosyasında kullanılabilecek XML özellikleri hakkında daha fazla bilgi edinmek için aşağıdaki referans belgelerine bakın:
android:description
android:packageNames
android:accessibilityEventTypes
android:accessibilityFlags
android:accessibilityFeedbackType
android:notificationTimeout
android:canRetrieveWindowContent
android:settingsActivity
Çalışma zamanında hangi yapılandırma ayarlarının dinamik olarak ayarlanabileceği hakkında daha fazla bilgi için AccessibilityServiceInfo
referans belgelerine bakın.
Erişilebilirlik hizmetinizi yapılandırma
Sisteme nasıl ve ne zaman çalıştırılacağını bildirmek için erişilebilirlik hizmetinizin yapılandırma değişkenlerini ayarlarken aşağıdakileri göz önünde bulundurun:
- Hangi etkinlik türlerine yanıt vermesini istiyorsunuz?
- Hizmetin tüm uygulamalar için mi yoksa yalnızca belirli paket adları için mi etkin olması gerekiyor?
- Hangi farklı geri bildirim türlerini kullanır?
Bu değişkenleri ayarlamak için iki seçeneğiniz vardır. Geriye dönük uyumlu seçenek, bunları setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)
kullanarak kod içinde ayarlamaktır. Bunun için onServiceConnected()
yöntemini geçersiz kılıp hizmetinizi aşağıdaki örnekte gösterildiği gibi burada yapılandırın:
Kotlin
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 }
Java
@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); }
İkinci seçenek, hizmeti bir XML dosyası kullanarak yapılandırmaktır. canRetrieveWindowContent
gibi belirli yapılandırma seçenekleri yalnızca hizmetinizi XML kullanarak yapılandırırsanız kullanılabilir. Önceki örnekte verilen yapılandırma seçenekleri, XML kullanılarak tanımlandığında şöyle görünür:
<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 kullanıyorsanız hizmet beyanınıza XML dosyasını işaret eden bir <meta-data>
etiketi ekleyerek manifest dosyanızda bunu belirtin. XML dosyanızı res/xml/serviceconfig.xml
içinde depolarsanız yeni etiket şöyle görünür:
<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>
Erişilebilirlik hizmeti yöntemleri
Bir erişilebilirlik hizmeti, AccessibilityService
sınıfını genişletmeli ve aşağıdaki yöntemleri bu sınıftan geçersiz kılmalıdır. Bu yöntemler, Android sisteminin çağrıştırdığı sırayla sunulur: hizmetin başlangıcından (onServiceConnected()
), çalışırken (onAccessibilityEvent()
, onInterrupt()
) kapandığı zamana (onUnbind()
) kadar.
onServiceConnected()
: (isteğe bağlı) sistem bu yöntemi erişilebilirlik hizmetinize bağlandığında çağırır. Bu yöntemi, ses yöneticisi veya cihaz titreşimi gibi kullanıcı geri bildirim sistemi hizmetlerine bağlanma da dahil olmak üzere hizmetiniz için tek seferlik kurulum adımları gerçekleştirmek için kullanın. Hizmetinizin yapılandırmasını çalışma zamanında belirlemek veya tek seferlik ayarlamalar yapmak istiyorsanızsetServiceInfo()
hizmetini çağırmak için bu konumu tercih edebilirsiniz.onAccessibilityEvent()
: (zorunlu) Sistem, erişilebilirlik hizmetiniz tarafından belirtilen etkinlik filtreleme parametreleriyle eşleşen birAccessibilityEvent
algıladığında (ör. kullanıcı bir düğmeye dokunduğunda veya erişilebilirlik hizmetinizin geri bildirim sağladığı bir uygulamadaki kullanıcı arayüzü kontrolüne odaklandığında) bu yöntemi geri çağırır. Sistem bu yöntemi çağırdığında, hizmet ilgiliAccessibilityEvent
bilgisini iletir. Hizmet daha sonra bunu yorumlayıp kullanıcıya geri bildirim sağlamak için kullanabilir. Bu yöntem, hizmetinizin yaşam döngüsü boyunca birçok kez çağrılabilir.onInterrupt()
: (zorunludur) Sistem, hizmetinizin sağladığı geri bildirimi kesintiye uğratmak istediğinde sistem bu yöntemi çağırır (genellikle odağı farklı bir kontrole taşımak gibi bir kullanıcı işlemi karşısında). Bu yöntem, hizmetinizin yaşam döngüsü boyunca birçok kez çağrılabilir.onUnbind()
: (isteğe bağlı) sistem erişilebilirlik hizmetini kapatmak üzereyken sistem bu yöntemi çağırır. Ses yöneticisi veya cihaz titreşimi gibi kullanıcı geri bildirim sistemi hizmetlerinin tahsisini kaldırmak da dahil olmak üzere tek seferlik kapatma prosedürlerini yapmak için bu yöntemi kullanın.
Bu geri çağırma yöntemleri erişilebilirlik hizmetiniz için temel yapıyı sağlar. Android sistemi tarafından sağlanan verilerin AccessibilityEvent
nesneleri biçiminde nasıl işleneceğine karar verebilir ve kullanıcıya geri bildirim sağlayabilirsiniz. Bir erişilebilirlik etkinliğinden bilgi alma hakkında daha fazla bilgi için Etkinlik ayrıntılarını alma bölümüne bakın.
Erişilebilirlik etkinliklerine kaydolun
Erişilebilirlik hizmeti yapılandırma parametrelerinin en önemli işlevlerinden biri, hizmetinizin işleyebileceği erişilebilirlik etkinliği türlerini belirleyebilmenizi sağlamaktır. Bu bilgilerin belirtilmesi, erişilebilirlik hizmetlerinin birbirleriyle iş birliği yapmasına olanak tanır ve size yalnızca belirli uygulamalardaki belirli etkinlik türlerini yönetme esnekliği sağlar. Etkinlik filtreleme aşağıdaki ölçütleri içerebilir:
Paket adları: Hizmetinizin erişilebilirlik etkinliklerini işlemesini istediğiniz uygulamaların paket adlarını belirtir. Bu parametre atlanırsa erişilebilirlik hizmetiniz, herhangi bir uygulama için hizmet erişilebilirlik etkinlikleri için kullanılabilir olarak kabul edilir. Bu parametreyi, erişilebilirlik hizmet yapılandırma dosyalarında
android:packageNames
özelliği ile virgülle ayrılmış liste olarak ayarlayabilir veyaAccessibilityServiceInfo.packageNames
üyesini kullanabilirsiniz.Etkinlik türleri: Hizmetinizin işlemesini istediğiniz erişilebilirlik etkinliklerinin türlerini belirtin. Bu parametreyi, erişilebilirlik hizmet yapılandırma dosyalarında
android:accessibilityEventTypes
özelliğini kullanarak|
karakteriyle ayrılmış bir liste olarak ayarlayabilirsiniz (ör.accessibilityEventTypes="typeViewClicked|typeViewFocused"
). DilersenizAccessibilityServiceInfo.eventTypes
üyesini kullanarak da ayarlayabilirsiniz.
Erişilebilirlik hizmetinizi ayarlarken hizmetinizin hangi etkinlikleri işleyebileceğini dikkatlice düşünün ve yalnızca bu etkinlikler için kaydolun. Kullanıcılar aynı anda birden fazla erişilebilirlik hizmetini etkinleştirebileceği için hizmetinizin işleyemeyeceği etkinlikleri kullanmaması gerekir. Diğer hizmetlerin kullanıcı deneyimini iyileştirmek için bu tür etkinlikleri işleyebileceğini unutmayın.
Erişilebilirlik ses düzeyi
Android 8.0 (API düzeyi 26) ve sonraki sürümleri çalıştıran cihazlar STREAM_ACCESSIBILITY
ses düzeyi kategorisini içerir. Bu kategori, erişilebilirlik hizmetinizin ses çıkışının ses düzeyini cihazdaki diğer seslerden bağımsız olarak kontrol etmenizi sağlar.
Erişilebilirlik hizmetleri, FLAG_ENABLE_ACCESSIBILITY_VOLUME
seçeneğini ayarlayarak bu akış türünü kullanabilir. Daha sonra, cihazın AudioManager
örneğinde adjustStreamVolume()
yöntemini çağırarak cihazın erişilebilirlik ses düzeyini değiştirebilirsiniz.
Aşağıdaki kod snippet'i, bir erişilebilirlik hizmetinin STREAM_ACCESSIBILITY
birim kategorisini nasıl kullanabileceğini gösterir:
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); } } }
Daha fazla bilgi için Google I/O 2017'de yayınlanan Android erişilebilirlik konusundaki yenilikler oturum videosunu 06:35'ten itibaren izleyin.
Erişilebilirlik kısayolu
Android 8.0 (API düzeyi 26) ve sonraki sürümleri çalıştıran cihazlarda kullanıcılar ses seviyesi tuşlarını aynı anda basılı tutarak istedikleri ekrandan istedikleri erişilebilirlik hizmetini etkinleştirebilir veya devre dışı bırakabilir. Bu kısayol TalkBack'i varsayılan olarak etkinleştirip devre dışı bıraksa da kullanıcılar, cihazlarında yüklü herhangi bir hizmeti etkinleştirmek veya devre dışı bırakmak için düğmeyi yapılandırabilir.
Kullanıcıların erişilebilirlik kısayolundan belirli bir erişilebilirlik hizmetine erişebilmesi için hizmetin, özelliği çalışma zamanında istemesi gerekir.
Daha fazla bilgi için Google I/O 2017'nin 13:25'ten itibaren yayınlanan Android erişilebilirlik konusundaki yenilikler oturum videosunu izleyin.
Erişilebilirlik düğmesi
Yazılımla oluşturulmuş gezinme alanı kullanan ve Android 8.0 (API düzeyi 26) veya sonraki sürümleri çalıştıran cihazlarda, gezinme çubuğunun sağ tarafında bir erişilebilirlik düğmesi bulunur. Kullanıcılar bu düğmeye bastıklarında, ekranda gösterilmekte olan içeriğe bağlı olarak, etkinleştirilmiş birkaç erişilebilirlik özelliğini ve hizmetini çağırabilirler.
Kullanıcıların erişilebilirlik düğmesini kullanarak belirli bir erişilebilirlik hizmetini çağırmasına izin vermek için hizmetin, AccessibilityServiceInfo
nesnesinin android:accessibilityFlags
özelliğine FLAG_REQUEST_ACCESSIBILITY_BUTTON
işaretini eklemesi gerekir. Daha sonra hizmet, registerAccessibilityButtonCallback()
kullanarak geri çağırmaları kaydedebilir.
Aşağıdaki kod snippet'i, bir erişilebilirlik hizmetini kullanıcının erişilebilirlik düğmesine basarak yanıt verecek şekilde nasıl yapılandırabileceğini gösterir:
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); } }
Daha fazla bilgi için Google I/O 2017'nin 16:28'de başlayan Android erişilebilirlik konusundaki yenilikler oturum videosunu izleyin.
Parmak izi hareketleri
Android 8.0 (API düzeyi 26) veya sonraki sürümleri çalıştıran cihazlardaki erişilebilirlik hizmetleri, cihazın parmak izi sensöründeki yönlü kaydırma hareketlerine (yukarı, aşağı, sol ve sağ) yanıt verebilir. Bir hizmeti bu etkileşimler hakkında geri çağırmalar alacak şekilde yapılandırmak için aşağıdaki sırayı tamamlayın:
USE_BIOMETRIC
iznini veCAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES
özelliğini beyan edin.android:accessibilityFlags
özelliği içindeFLAG_REQUEST_FINGERPRINT_GESTURES
işaretini ayarlayın.registerFingerprintGestureCallback()
kullanarak geri aramalara kaydolun.
Tüm cihazlarda parmak izi sensörü bulunmayabilir. Bir cihazın sensörü destekleyip desteklemediğini belirlemek için isHardwareDetected()
yöntemini kullanın. Parmak izi sensörü içeren bir cihazda bile, hizmetiniz kimlik doğrulama amacıyla kullanılırken sensörü kullanamaz. Sensörün ne zaman kullanılabilir olduğunu belirlemek için isGestureDetectionAvailable()
yöntemini çağırın ve onGestureDetectionAvailabilityChanged()
geri çağırmasını uygulayın.
Aşağıdaki kod snippet'i, sanal oyun tahtasında gezinmek için parmak izi hareketlerini kullanmaya ilişkin bir örnek göstermektedir:
// 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" ... />
Kotlin
// 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) } } }
Java
// 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); } } }
Daha fazla bilgi için Google I/O 2017'de 09:03'ten itibaren yayınlanan Android erişilebilirlik konusundaki yenilikler oturum videosunu izleyin.
Çok dilde metin okuma
Android 8.0 (API düzeyi 26) sürümünden başlayarak Android'in metin okuma (TTS) hizmeti, tek bir metin bloğunda birden çok dilde ifadeleri tanımlayabilir ve söyleyebilir. Bu otomatik dil değiştirme özelliğini bir erişilebilirlik hizmetinde etkinleştirmek için tüm dizeleri aşağıdaki kod snippet'inde gösterildiği gibi LocaleSpan
nesnelerinin içinde sarmalayın:
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; }
Daha fazla bilgi için Google I/O 2017'nin 10:59'da başlayan Android erişilebilirlik konusundaki yenilikler oturum videosunu izleyin.
Kullanıcılar adına işlem yapma
2011'den itibaren erişilebilirlik hizmetleri, giriş odağını değiştirmek ve kullanıcı arayüzü öğelerini seçmek (etkinleştirmek) dahil olmak üzere kullanıcılar adına hareket edebilir. 2012'de, işlemlerin kapsamı, kaydırma listelerini ve metin alanlarıyla etkileşimde bulunacak şekilde genişletildi. Erişilebilirlik hizmetleri ayrıca ana ekrana gitme, Geri düğmesine basma, bildirim ekranını ve son uygulamalar listesini açma gibi genel işlemler de yapabilir. Android, 2012'den beri tüm görünür öğeleri bir erişilebilirlik hizmeti tarafından seçilebilir hale getiren erişilebilirlik odağı içermektedir.
Bu özellikler, erişilebilirlik hizmetleri geliştiricilerinin hareketle gezinme gibi alternatif gezinme modları oluşturmasına ve engelli kullanıcıların Android destekli cihazlarını daha iyi kontrol etmesine olanak tanır.
Hareketleri dinle
Erişilebilirlik hizmetleri, belirli hareketleri dinleyebilir ve kullanıcının adına hareket ederek yanıt verebilir. Bu özellik, erişilebilirlik hizmetinizin Dokunarak Araştırma özelliğinin etkinleştirilmesini gerektirir. Hizmetiniz, hizmetin AccessibilityServiceInfo
örneğinin flags
üyesini aşağıdaki örnekte gösterildiği gibi FLAG_REQUEST_TOUCH_EXPLORATION_MODE
olarak ayarlayarak bu etkinleştirme işlemini isteyebilir.
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; } ... }
Hizmetiniz Dokunarak Keşfet'in etkinleştirilmesini istedikten sonra, kullanıcı özelliğin etkin değilse etkin olmasına izin vermelidir. Bu özellik etkin olduğunda hizmetiniz, hizmetinizin onGesture()
geri çağırma yöntemiyle erişilebilirlik hareketleri hakkında bildirim alır ve kullanıcı adına hareket ederek yanıt verebilir.
Devam eden hareketler
Android 8.0 (API düzeyi 26) çalıştıran cihazlar, devam eden hareketleri veya birden fazla Path
nesnesi içeren programatik hareketleri destekler.
Bir çizgi sırası belirtirken, aşağıdaki kod snippet'inde gösterildiği gibi, GestureDescription.StrokeDescription
oluşturucuda son willContinue
bağımsız değişkenini kullanarak
bu fırçaların aynı programatik harekete ait olduğunu belirtebilirsiniz:
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); }
Daha fazla bilgi için Google I/O 2017'nin 15:47'de başlayan Android erişilebilirlik konusundaki yenilikler oturum videosunu izleyin.
Erişilebilirlik işlemlerini kullanma
Erişilebilirlik hizmetleri, uygulamalarla etkileşimleri basitleştirmek ve daha üretken olmak için kullanıcıların adına hareket edebilir. Erişilebilirlik hizmetlerinin işlem gerçekleştirme özelliği 2011'de eklendi ve 2012'de önemli ölçüde genişletildi.
Kullanıcılar adına işlem yapmak için erişilebilirlik hizmetinizin uygulamalardan etkinlik almak üzere kaydolması ve hizmet yapılandırma dosyasında android:canRetrieveWindowContent
ayarını true
olarak yaparak uygulamaların içeriğini görüntüleme izni istemesi gerekir. Hizmetiniz etkinlikleri aldığında, getSource()
kullanarak etkinlikten AccessibilityNodeInfo
nesnesini alabilir.
Ardından AccessibilityNodeInfo
nesnesiyle hizmetiniz, gerçekleştirilecek işlemi belirlemek için görünüm hiyerarşisini inceleyebilir ve performAction()
ile kullanıcı için işlem yapabilir.
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. // Act 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. // Act on behalf of the user. nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); // Recycle the nodeInfo object. nodeInfo.recycle(); } ... }
performAction()
yöntemi, hizmetinizin uygulama içinde işlem yapmasını sağlar. Hizmetinizin genel bir işlem yapması gerekiyorsa (ör. ana ekrana gitme, Geri düğmesine dokunma veya bildirim ekranını ya da son uygulamalar listesini açma gibi) performGlobalAction()
yöntemini kullanın.
Odak türlerini kullanma
2012'de Android, erişilebilirlik odağı adı verilen bir kullanıcı arayüzü odağını kullanıma sunmuştur. Erişilebilirlik hizmetleri, görünür herhangi bir kullanıcı arayüzü öğesini seçmek ve üzerinde işlem yapmak için bu odağı kullanabilir. Bu odak türü, bir kullanıcı karakter yazdığında, klavyede Enter tuşuna bastığında veya D-pad'in orta düğmesine bastığında ekrandaki kullanıcı arayüzü öğesinin hangi giriş alacağını belirleyen giriş odağından farklıdır.
Kullanıcı arayüzündeki bir öğe giriş odağına sahipken başka bir öğe erişilebilirlik odağı olabilir. Erişilebilirlik odağının amacı, erişilebilirlik hizmetlerine, öğenin sistem bakış açısından giriş odaklı olup olmamasından bağımsız olarak ekrandaki görünür öğelerle etkileşim kurma yöntemi sunmaktır. Erişilebilirlik hizmetinizin, uygulamaların giriş öğeleriyle doğru şekilde etkileşimde bulunduğundan emin olmak için tipik bir uygulamayı kullanırken hizmetinizi test etmek üzere uygulamanın erişilebilirliğini test etme yönergelerini uygulayın.
Bir erişilebilirlik hizmeti, AccessibilityNodeInfo.findFocus()
yöntemini kullanarak hangi kullanıcı arayüzü öğesinin giriş odağı veya erişilebilirlik odağı olduğunu belirleyebilir. focusSearch()
yöntemini kullanarak giriş odağıyla seçilebilecek öğeleri de arayabilirsiniz. Son olarak, erişilebilirlik hizmetiniz performAction(AccessibilityNodeInfo.ACTION_SET_ACCESSIBILITY_FOCUS)
yöntemini kullanarak erişilebilirlik odağını ayarlayabilir.
Bilgi toplama
Erişilebilirlik hizmetleri, kullanıcı tarafından sağlanan etkinlik ayrıntıları, metin ve sayılar gibi temel bilgileri toplamak ve temsil etmek için kullanılan standart yöntemlere sahiptir.
Aralık değişikliği ayrıntılarını al
Android 9 (API düzeyi 28) ve sonraki sürümler, bir uygulama aynı anda birden çok pencereyi yeniden çizdiğinde uygulamaların pencere güncellemelerini takip etmesine olanak tanır. TYPE_WINDOWS_CHANGED
etkinliği gerçekleştiğinde pencerelerin nasıl değiştiğini belirlemek için getWindowChanges()
API'yi kullanın. Çoklu pencere güncellemesi sırasında her pencere kendi etkinlik grubunu oluşturur. getSource()
yöntemi, her bir etkinlikle ilişkili pencerenin kök görünümünü döndürür.
Bir uygulama, View
nesneleri için erişilebilirlik bölmesi başlıklarını tanımlarsa hizmetiniz, uygulamanın kullanıcı arayüzü güncellendiğinde bunu algılayabilir. Bir TYPE_WINDOW_STATE_CHANGED
etkinliği gerçekleştiğinde aralığın nasıl değişeceğini belirlemek için getContentChangeTypes()
tarafından döndürülen türleri kullanın. Örneğin, çerçeve bir bölmenin yeni bir başlığı
olduğunda veya bölmenin kaybolduğunu algılayabilir.
Etkinlik ayrıntılarını alma
Android, erişilebilirlik hizmetlerine AccessibilityEvent
nesneleri üzerinden kullanıcı arayüzü etkileşimi hakkında bilgi sağlar. Önceki Android sürümlerinde erişilebilirlik etkinliğinde bulunan bilgiler, kullanıcıların seçtiği kullanıcı arayüzü kontrolü hakkında önemli ayrıntılar sağlarken sınırlı bağlam bilgileri sunuyordu. Çoğu durumda, bu eksik bağlam bilgileri, seçilen kontrolün anlamını anlamak açısından kritik öneme sahip olabilir.
Bağlamın kritik olduğu arayüze örnek olarak takvim veya gün planlayıcı verilebilir. Kullanıcı pazartesiden cumaya bir gün listesinde 16:00'da bir zaman aralığı seçerse ve erişilebilirlik hizmeti"16:00" dediğini anons eder ancak hafta içi adını, ayın gününü veya ay adını duyurmazsa ortaya çıkan geri bildirim kafa karıştırıcı olur. Bu durumda, toplantı planlamak isteyen kullanıcı için kullanıcı arayüzü kontrolünün bağlamı kritik önem taşır.
2011'den beri Android, görünüm hiyerarşisine göre erişilebilirlik etkinlikleri oluşturarak bir erişilebilirlik hizmetinin kullanıcı arayüzü etkileşimi hakkında edinebileceği bilgi miktarını önemli ölçüde artırmaktadır. Görünüm hiyerarşisi, bileşeni (üst öğelerini) içeren kullanıcı arayüzü bileşenleri ve bu bileşenin (alt öğeleri) içerebileceği kullanıcı arayüzü öğeleri kümesidir. Bu sayede Android, erişilebilirlik etkinlikleri hakkında daha zengin ayrıntılar sağlayarak erişilebilirlik hizmetlerinin kullanıcılara daha yararlı geri bildirimler sağlamasına olanak tanıyabilir.
Erişilebilirlik hizmeti, sistem tarafından hizmetin onAccessibilityEvent()
geri çağırma yöntemine iletilen AccessibilityEvent
aracılığıyla kullanıcı arayüzü etkinliği hakkında bilgi alır. Bu nesne, üzerinde işlem yapılan nesnenin türü, açıklayıcı metni ve diğer ayrıntılar dahil olmak üzere etkinlikle ilgili ayrıntıları sağlar.
AccessibilityEvent.getRecordCount()
vegetRecord(int)
: Bu yöntemlerle, sistem tarafından size iletilenAccessibilityEvent
'a katkıda bulunanAccessibilityRecord
nesne kümesini alabilirsiniz. Bu ayrıntı düzeyi, erişilebilirlik hizmetinizi tetikleyen etkinlik hakkında daha fazla bağlam sağlar.AccessibilityRecord.getSource()
: Bu yöntem birAccessibilityNodeInfo
nesnesi döndürür. Bu nesne, erişilebilirlik etkinliğini oluşturan bileşenin görünüm düzeni hiyerarşisini (üst öğeler ve alt öğeler) istemenize olanak tanır. Bu özellik, bir erişilebilirlik hizmetinin ilgili görüntülemelerin veya çocukların görüntülemelerinin içeriği ve durumu dahil olmak üzere bir etkinliğin tüm bağlamını araştırmasına olanak tanır.
Android platformu, AccessibilityService
öğelerinin görünüm hiyerarşisini sorgulamasına imkan vererek bir etkinliği oluşturan kullanıcı arayüzü bileşeninin yanı sıra üst ve alt öğeleri hakkında bilgi toplar. Bunu yapmak için XML yapılandırmanızda aşağıdaki satırı ayarlayın:
android:canRetrieveWindowContent="true"
Bu işlem tamamlandıktan sonra getSource()
kullanarak bir AccessibilityNodeInfo
nesnesi alın.
Bu çağrı yalnızca etkinliğin kaynaklandığı pencere hâlâ etkin penceredeyse bir nesne döndürür. Aksi takdirde null değerini döndürdüğünden uygun bir şekilde davranın.
Aşağıdaki örnekte, bir etkinlik alındığında kod aşağıdakileri yapar:
- Etkinliğin gerçekleştiği görünümün üst öğesini hemen alır.
- Bu görünümde, alt görünümler olarak bir etiket ve onay kutusu olup olmadığına bakar.
- Etiket bunları bulursa kullanıcıya bildirmek için etiketi ve işaretli olup olmadığını belirten bir dize oluşturur.
Görünüm hiyerarşisinde gezinilirken herhangi bir noktada boş değer döndürülürse yöntem sessizce işlemden vazgeçer.
Kotlin
// 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) }
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 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); }
Artık eksiksiz ve çalışan bir erişilebilirlik hizmetiniz var. Android'in metin okuma motorunu ekleyerek veya dokunsal geri bildirim sağlamak için bir Vibrator
kullanarak bunun kullanıcıyla nasıl etkileşimde bulunacağını yapılandırmayı deneyin.
Metni işle
Android 8.0 (API düzeyi 26) ve sonraki sürümleri çalıştıran cihazlarda erişilebilirlik hizmetlerinin ekranda görünen belirli metin birimlerini tanımlamasını ve bunlar üzerinde çalışmasını kolaylaştıran çeşitli metin işleme özellikleri bulunur.
İpuçları
Android 9 (API düzeyi 28), uygulamaların kullanıcı arayüzündeki ipuçlarına erişmenizi sağlayan çeşitli özellikler sunar. İpucu metnini okumak için getTooltipText()
simgesini, View
örneklerine ise ipuçlarını gösterme veya gizleme talimatı vermek için ACTION_SHOW_TOOLTIP
ve ACTION_HIDE_TOOLTIP
öğelerini kullanın.
İpucu metni
2017'den itibaren Android'de, metin tabanlı bir nesnenin ipucu metniyle etkileşimde bulunmak için çeşitli yöntemler bulunmaktadır:
isShowingHintText()
vesetShowingHintText()
yöntemleri, düğümün mevcut metin içeriğinin düğümün ipucu metnini temsil edip etmediğini sırasıyla belirtir ve belirler.getHintText()
, ipucu metnine erişim sağlar. Bir nesne ipucu metni görüntülemese bilegetHintText()
çağrısı başarılı olur.
Ekrandaki metin karakterlerinin konumları
Android 8.0 (API düzeyi 26) ve sonraki sürümleri çalıştıran cihazlarda erişilebilirlik hizmetleri, TextView
widget'ındaki her görünür karakterin sınırlayıcı kutusu için ekran koordinatlarını belirleyebilir. Hizmetler bu koordinatları refreshWithExtraData()
çağırıp ilk bağımsız değişken olarak EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
, ikinci bağımsız değişken olarak da Bundle
nesnesini iletir. Yöntem yürütüldüğünde, sistem Bundle
bağımsız değişkenini ayrıştırılabilir bir Rect
nesne dizisiyle doldurur. Her Rect
nesnesi, belirli bir karakterin sınırlayıcı kutusunu temsil eder.
Standartlaştırılmış tek taraflı aralık değerleri
Bazı AccessibilityNodeInfo
nesneleri, kullanıcı arayüzü öğesinin bir değer aralığı alabildiğini belirtmek için AccessibilityNodeInfo.RangeInfo
örneğini kullanır. RangeInfo.obtain()
kullanarak bir aralık oluştururken veya getMin()
ve getMax()
kullanarak aralığın uç değerlerini alırken, Android 8.0 (API düzeyi 26) ve sonraki sürümleri çalıştıran cihazların tek taraflı aralıkları standartlaştırılmış bir şekilde temsil ettiğini unutmayın:
- Minimum değeri olmayan aralıklar için
Float.NEGATIVE_INFINITY
en düşük değeri temsil eder. - Maksimum değeri olmayan aralıklar için
Float.POSITIVE_INFINITY
maksimum değeri temsil eder.
Erişilebilirlik etkinliklerine yanıt verme
Hizmetiniz etkinlikleri çalıştıracak ve dinleyecek şekilde ayarlandığına göre AccessibilityEvent
geldiğinde ne yapılacağını bilmesi için kod yazın. onAccessibilityEvent(AccessibilityEvent)
yöntemini geçersiz kılarak başlayın. Bu yöntemde, etkinliğin türünü belirlemek için getEventType()
ve etkinliği tetikleyen görünümle ilişkilendirilmiş tüm etiket metinlerini ayıklamak için getContentDescription()
kullanın:
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); ... }
Ek kaynaklar
Daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın: