W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
編寫:K0ST - 原文:http://developer.android.com/training/accessibility/service.html
本課程將教您:
創(chuàng)建可達(dá)性服務(wù)(Accessibility Service)
配置可達(dá)性服務(wù)(Accessibility Service)
響應(yīng)可達(dá)性事件(AccessibilityEvents)
從View層級中提取更多信息
Accessibility Service是Android系統(tǒng)框架提供給安裝在設(shè)備上應(yīng)用的一個可選的導(dǎo)航反饋特性。Accessibility Service 可以替代應(yīng)用與用戶交流反饋,比如將文本轉(zhuǎn)化為語音提示,或是用戶的手指懸停在屏幕上一個較重要的區(qū)域時的觸摸反饋等。本課程將教您如何創(chuàng)建一個Accessibility Service,同時處理來自應(yīng)用的信息,并將這些信息反饋給用戶。
Accessibility Service可以綁定在一個正常的應(yīng)用中,或者是單獨(dú)的一個Android項(xiàng)目都可以。創(chuàng)建一個Accessibility Service的步驟與創(chuàng)建普通Service的步驟相似,在你的項(xiàng)目中創(chuàng)建一個繼承于AccessibilityService的類:
package com.example.android.apis.accessibility;
import android.accessibilityservice.AccessibilityService;
public class MyAccessibilityService extends AccessibilityService {
...
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
}
@Override
public void onInterrupt() {
}
...
}
與其他Service類似,你必須在manifest文件當(dāng)中聲明這個Service。記得標(biāo)明它監(jiān)聽處理了android.accessibilityservice
事件,以便Service在其他應(yīng)用產(chǎn)生AccessibilityEvent的時候被調(diào)用。
<application ...>
...
<service android:name=".MyAccessibilityService">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
. . .
</service>
...
</application>
如果你為這個Service創(chuàng)建了一個新項(xiàng)目,且僅僅是一個Service而不準(zhǔn)備做成一個應(yīng)用,那么你就可以移除啟動的Activity(一般為MainActivity.java),同樣也記得在manifest中將這個Activity聲明移除。
設(shè)置Accessibility Service的配置變量會告訴系統(tǒng)如何讓Service運(yùn)行與何時運(yùn)行。你希望響應(yīng)哪種類型的事件?Service是否對所有的應(yīng)用有效還是對部分指定包名的應(yīng)用有效?使用哪些不同類型的反饋?
你有兩種設(shè)置這些變量屬性的方法,一種向下兼容的辦法是通過代碼來進(jìn)行設(shè)定,使用setServiceInfo
(android.accessibilityservice.AccessibilityServiceInfo)。你需要重寫(override)onServiceConnected()
方法,并在這里進(jìn)行Service的配置。
@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);
}
在Android 4.0之后,就用另一種方式來設(shè)置了:通過設(shè)置XML文件來進(jìn)行配置。一些特性的選項(xiàng)比如canRetrieveWindowContent
僅僅可以在XML可以配置。對于上面所示的相應(yīng)的配置,利用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進(jìn)行配置,那么請確保在manifest文件中通過< meta-data >標(biāo)簽指定這個配置文件。假設(shè)此配置文件存放的地址為:res/xml/serviceconfig.xml
,那么標(biāo)簽應(yīng)該如下:
<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>
現(xiàn)在你的Service已經(jīng)配置好并可以監(jiān)聽Accessibility Event了,來寫一些響應(yīng)這些事件的代碼吧!首先就是要重寫onAccessibilityEvent(AccessibilityEvent)方法,在這個方法中,使用getEventType()
來確定事件的類型,使用getContentDescription()
來提取產(chǎn)生事件的View的相關(guān)的文本標(biāo)簽。
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
final int eventType = event.getEventType();
String eventText = null;
switch(eventType) {
case AccessibilityEvent.TYPE_VIEW_CLICKED:
eventText = "Focused: ";
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);
...
}
這一步并不是必要步驟,但是卻非常有用。Android 4.0版本中增加了一個新特性,就是能夠用AccessibilityService來遍歷View層級,并從產(chǎn)生Accessibility 事件的組件與它的父子組件中提取必要的信息。為了實(shí)現(xiàn)這個目的,你需要在XML文件中進(jìn)行如下的配置:
android:canRetrieveWindowContent="true"
一旦完成,使用getSource())獲取一個AccessibilityNodeInfo對象,如果觸發(fā)事件的窗口是活動窗口,該調(diào)用只返回一個對象,如果不是,它將返回null,做出相應(yīng)的反響。下面的示例是一個代碼片段,當(dāng)它接收到一個事件時,執(zhí)行以下步驟:
// 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);
}
現(xiàn)在你已經(jīng)實(shí)現(xiàn)了一個完整可運(yùn)行的Accessibility Service。嘗試著調(diào)整它與用戶的交互方式吧!比如添加語音引擎,或者添加震動來提供觸覺上的反饋都是不錯的選擇!
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: