Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android——實現無障礙

Android——實現無障礙

編輯:關於Android編程

簡介

當說到想要達到盡可能廣泛的用戶基數,重視Android應用的無障礙性能很重要。用戶界面上的提示可能對大多數用戶有用,例如當一個按鈕被按下後有視覺變化,如果用戶有視力障礙,這就不是最優的方案。

該課程展示了怎樣充分利用內置Android框架的無障礙功能。該課程包含了怎樣利用焦點導航和內容描述等平台特性,從無障礙方面對應用進行優化;也包含怎樣構建無障礙服務,方便用戶與任何Android應用進行交互,不只是自己開發的應用。

 

1.1 課程

開發無障礙應用

學習讓Android應用無障礙。允許鍵盤或定向墊的簡單導航,設置標簽並發送可以被無障礙服務解釋的事件,以獲得流暢的用戶體驗。

開發無障礙服務

開發一個監聽無障礙事件的無障礙服務,在這些事件中獲得事件類型和內容描述等的信息,並使用這些信息與用戶交流。樣例將會使用文本轉語音引擎講述給用戶。

無障礙測試清單

學習怎樣測試應用的無障礙特性。

開發無障礙應用

Android有幾個集成到平台的焦點無障礙特性,這讓為視覺和肢體障礙的用戶進行應用優化更為簡單。但是,什麼是正確的優化,或利用平台達到目的的最簡單方式,並不總是顯而易見。該課程展示了怎樣實現這些方法和平台特性,並使用這些方法和特性可以開發出支持無障礙的Android應用。

2.1 添加內容描述

一個精心設計的用戶界面(UI)經常有不需要精確標簽向用戶標識目的的元素。在任務列表應用中,一個復選框後跟隨一個條目,有非常明顯的目的,在文件管理應用中卻是個垃圾桶。但是,對於視覺障礙的用戶,卻需要其他UI提示。

幸運的是,在應用中給UI元素添加標簽非常容易,這些標簽可以被像TalkBack一樣基於語音的無障礙服務大聲朗讀給用戶。如果有標簽在應用的生命周期內不會改變(例如“暫停”或“購買”),可以通過在XML布局文件中設置UI元素的android:contentDescription屬性添加,如本樣例中所示:

 

但是,在很多情景下,需要根據上下文確定內容描述,例如開關按鈕的狀態、或列表條目等的可選擇數據。使用setContentDescription()在運行時編輯內容描述,如下:
String contentDescription = "Select " + strValues[position];
label.setContentDescription(contentDescription);

將這些加入代碼中,是提升應用無障礙特性的最簡單的方式,但只是最有效的方法之一。嘗試在所有有有用信息的地方添加內容描述,但是應該避免標記無用信息的誤區。例如,不要給應用圖標設置內容描述為“應用圖標”。這只會增加用戶在導航時從界面中抽取有用信息的噪音。

試試吧!下載TalkBack(Google發布的一個無障礙服務),並在“設置>無障礙>TalkBack”中打開,然後導航自己的應用,並聽取TalkBack提供的音頻提示。

2.2 焦點導航設計

應用應該支持多種導航方式,不只是觸摸屏幕。很多Android設備支持硬件導航,例如D-pad、方向鍵、或軌跡球,不只是觸摸屏。另外,後期發布的Android也支持連接外部設備,例如通過USB或藍牙連接的鍵盤。

為了支持這種導航模式,用戶應該能夠導航到的所有可導航的元素,都需要被設置為可聚焦。該修改可以在應用運行時在對應UI控件上使用View.setFocusable()方法實現,或者通過在XML布局文件中設置android:focusable屬性實現。

同時,每個UI控件有4個屬性,android:nextFocusUp、android:nextFocusDown、android:nextFocusLeft和android:nextFocusRight,當用戶在特定方向導航時,可以用來指定下一個接收焦點的視圖。雖然平台會自動根據布局臨近自動決定導航順序,但當該導航順序不適合應用時,開發者可以使用這些屬性重寫導航順序,如下例,呈現了一個按鈕和標簽,且都可聚焦,例如向下滑,焦點從按鈕轉移到文本視圖,向上滑,焦點回到按鈕。

驗證應用在這些情景下的工作符合直覺。最簡單的方式是在Android模擬器中簡單地運行應用,並使用模擬方向鍵導航UI,使用OK按鈕代替觸摸選擇UI控件。

 

2.3 發送無障礙事件

如果在Android框架中使用視圖組件,無論何時選擇一個條目或改變UI中的焦點時,都會創建一個AccessibilityEvent。這些事件被無障礙服務檢測,讓它能提供文本轉語音類的服務給用戶。

如果寫了一個自定義視圖,保證在適當的時候發送事件。通過調用具有一個呈現已發生事件類型參數的sendAccessibilityEvent(int)生成事件。當前支持的事件類型完全列表可在AccessibilityEvent參考文檔中找到。

作為一個樣例,如果想要將一個圖片擴展為聚焦時可使用鍵盤輸入標題,需要發送一個TYPE_VIEW_TEXT_CHANGED事件,盡管是不正常地輸入到image視圖。生成事件的代碼如下所示:

public void onTextChanged(String before, String after) {
 ...
 if(AccessibilityManager.getInstance(mContext).isEnabled()) {   
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
    }
    ...
}

 

2.4 測試應用

當在應用中加入無障礙功能時,必須去測試它。為了測試內容描述和無障礙事件,安裝和啟用無障礙服務。一個選擇是TalkBack,一個免費的、開源的、在Google Play上可獲得的屏幕閱讀器。啟用服務,測試應用中的所有導航流程並聽取語音反饋。

同時,嘗試使用定向控制器而不是觸摸屏幕,導航應用。如果可獲得,可以使用D-pad或軌跡球等物理設備。如果沒有,可使用Android模擬器模擬鍵盤控制。

在服務提供反饋和定向導航應用時,應該有一種感覺,就像是在沒有任何視覺提示的情況下導航應用。當問題出現時及時修復,測試結束後將會得到一個更加無障礙的Android應用。

 

 

開發無障礙服務

 

無障礙服務是Android框架的一個特性,被設計用來代替安裝在Android設備上的應用,為用戶提供替代導航反饋。無障礙服務可以代表應用與用戶進行交流,例如,當用戶訪問屏幕上的重要位置時,將文本轉化為語音或提供觸覺反饋。本課程覆蓋了如何創建無障礙服務、處理從應用接收到的信息,並把信息報告給用戶。

3.1 創建無障礙服務

一個無障礙服務可以被捆綁在一個普通應用中,或被作為一個獨立Android工程進行創建。在任何情況下,創建該服務的步驟是相同的。在工程內,創建一個繼承自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() {
    }
 
...
}

像其他服務一樣,也應該在清單文件(manifest file)中聲明該服務。記得指明想要該服務處理的android.accessibilityservice intent,這樣當應用發送AccessibilityEvent時該服務可被調用。


 ...     . . .  ... 

如果為該服務創建了一個新工程,且不打算創建一個應用,可以從源代碼中移除啟動Activity類(通常被稱為MainActivity.java)。同時也要記得從清單文件中移除相應的activity元素。

3.2 配置無障礙服務

為無障礙服務設置配置變量,告知系統想要運行服務的方式和時間。哪些事件類型是想要處理的?服務應該被所有應用激活還是只被特定的包名激活?服務會使用哪些不同的反饋類型?

有兩種選擇來設置這些變量。向後兼容的選擇是在代碼中使用setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)設置它們。要做到該選擇,需要重寫onServiceConnected()方法並在該方法中配置無障礙服務。

@Override
public void onServiceConnected() {
//設置此服務想要監聽的事件類型。其他類型將不會傳遞到此服務。
info.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED |
            AccessibilityEvent.TYPE_VIEW_FOCUSED;
//如果只想該服務運行在指定的應用中,在這裡設置包名。
//否則當服務被激活,它將監聽所有應用的事件。
info.packageNames = new String[]{"com.example.android.myFirstApp", "com.example.android.mySecondApp"};	
//設置服務將提供的反饋類型。
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
//當沒有為已生成AccessibilityEvent類型提供指定包名時,默認服務
//才會被調用。該服務*是*指定應用的,所以該標志(flag)是不是必須的。
//如果這是一個通用的服務,設置默認標志(flag)是值得考慮的。

// info.flags = AccessibilityServiceInfo.DEFAULT;

info.notificationTimeout = 100;

this.setServiceInfo(info);
}

第二種選擇是使用XML文件配置服務。某些配置選項,如canRetrieveWindowContent,只有在使用XML配置服務時才可用。與上述相同的配置選項,使用XML定義,如下:


如果走XML路線,通過在服務聲明中添加指向XML文件的標簽,保證在清單文件中引用該XML文件。如果將XML文件保存在res/xml/serviceconfig.xml中,新的標簽如下:





3.3 AccessibilityEvent響應

現在無障礙服務已經啟動運行和監聽事件,寫一些代碼,讓它知道當一個AccessibilityEvent真的到來時該做什麼吧!首先重寫onAccessibilityEvent(AccessibilityEvent)方法。在此方法中,用getEventType()確定事件類型,並使用getContentDescription()抽取與發出事件的視圖相關聯的所有標簽文本。

@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();
    //優化文本,例如將組合的字符串朗讀給用戶。
    speakToUser(eventText);
    ...
}
該步驟是可選的,卻是非常有用的。Android平台為每個AccessibilityService提供了查詢視圖層次的能力,來收集生成事件的UI組件、以及其父視圖和子視圖的信息。為了做到這點,確保在XML配置文件中設置了以下代碼:3.4 為獲取更多上下文查詢視圖層次

 

android:canRetrieveWindowContent="true"

一旦這樣做了,可使用getSource()得到一個AccessibilityNodeInfo對象。如果生成該事件的窗口仍然是活躍窗口,此調用只返回一個對象。如果是非活躍窗口,將返回空,行為相應改變。下面的樣例是一個代碼片段,當服務接收到事件時,執行以下行為:

1.立即抓取生成事件視圖的父視圖;

2.在此視圖中,尋找作為子視圖的標簽和復選框;

3.如果找到它們,創建一個表明標簽和它是否被選中的字符串,報告給用戶

4.如果在遍歷視圖層次時,在任何點返回空值,此方法將被安靜的放棄。

//使用AccessibilityNodeInfo,代替onAccessibilityEvent
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    AccessibilityNodeInfo source = event.getSource();
    if (source == null) {
        return;
    }

//抓取發送事件視圖的父視圖。
    AccessibilityNodeInfo rowNode = getListItemNodeInfo(source);
    if (rowNode == null) {
        return;
    }

//使用父視圖,得到標簽和復選框兩個子節點的引用。
    AccessibilityNodeInfo labelNode = rowNode.getChild(0);
    if (labelNode == null) {
        rowNode.recycle();
        return;
    }

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

    //根據內部標簽的文本和復選框的狀態,來確定任務內容和任務是否完成。
    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設備的無障礙特性。

4.1 測試目標

無障礙測試應該有以下高級別的目標:

 

在沒有視覺幫助下啟動和使用應用;應用中的所有任務流程可以使用定向控制進行簡單導航,並提供明確適當的反饋。

 

4.2 測試需求

為了保證應用最低級別的無障礙,必須完成以下測試。

1.定向控制:驗證應用在不使用觸摸屏的情況下可以被操作。嘗試只使用定向控制器在應用中完成主要任務。在模擬器中使用鍵盤和D-pad控制或在Android4.1(API級別16)或以上的設備上使用手勢導航。

注意:鍵盤和D-pads提供與無障礙手勢不同的導航路徑。手勢允許用戶聚焦屏幕上幾乎所有的內容,鍵盤和D-pad導航只允許聚焦輸入區域和按鈕。

2.TalkBack音頻反饋:當啟用TalkBack並且控件被聚焦時,驗證提供信息的用戶界面控件(圖形或文本)或允許用戶的操作有清楚明確的音頻描述。使用定向控制在應用布局元素間移動焦點。

3.觸摸浏覽提示:當啟用觸摸浏覽時,驗證提供信息的用戶界面控件(圖形或文本)或允許用戶的操作有清楚明確的音頻描述。所有內容或控件區域都應該提供音頻反饋。

4.可觸摸控件大小:用戶可選擇或操作的所有控件最小寬高應為48dp(大概9mm),是Android設計中所推薦的。

5.啟用TalkBack時的手勢響應:驗證應用特定手勢,例如縮放圖片、滾動列表、在頁面間掃動或導航轉盤控制,在開啟TalkBack的情況下可持續工作。如果這些手勢不起作用,必須為該操作提供一個替代交互。

6.非純音頻反饋:音頻反饋必須總是有第二種反饋機制支持聽障用戶的使用,例如:信息到達時的聲音警報應該伴隨一個系統通知,觸覺反饋(如果有)或其他視覺警告。

4.3 測試建議

推薦進行以下測試保證應用的無障礙特性。如果未測試這些條目,可能會影響應用整體的無障礙特性和質量。

1.重復音頻提示:檢查臨近的相關控件(例如在列表中有多個組件的條目)沒有機械地重復相同的音頻反饋。例如,在包含聯系人圖像、文本名字和標題的聯系人列表裡面,每一個條目不應該機械地重復“鮑勃·史密斯”提示。

2.音頻提示超載或不足:檢查臨近的有關控件提供適當級別的音頻反饋,讓用戶理解和操作屏幕元素。提示太少或太多都會讓用戶在理解和使用控件時存在困難。

4.4 特殊實例和注意事項

以下列表描述了保證應用無障礙需要測試的特定場景。這裡描述的某些或所有情況可能適用於正在開發的應用。復查該列表,驗證這些特殊實例是否適用並采取合適的措施。

1.復查開發特殊實例和注意事項:復查無障礙開發的特殊實例列表並在應用中測試已使用的實例。

2.功能改變控件的提示:根據應用上下文或流程改變功能的按鈕或其他控件必須提供適用於當前功能的音頻提示。例如,一個按鈕,功能從播放視頻變為暫停視頻,應該提供適用於當前狀態的音頻提示。

3.視頻播放和字幕:如果應用提供視頻播放功能,驗證該功能支持字幕來幫助聽障用戶。視頻播放控件必須清楚說明視頻字幕可獲得,且提供簡單方式以啟用字幕。

4.5 測試無障礙特性

無障礙功能的測試,例如TalkBack、觸摸浏覽和無障礙手勢,需要啟用測試設備中的這些功能。本章節描述了為了無障礙測試如何啟動這些功能。

4.5.1 測試音頻反饋

Android設備上的無障礙音頻反饋功能提供音頻提示,在應用中導航時講述屏幕內容。通過在Android設備中啟用這個功能,可以測試視障用戶的應用體驗。

Android中的用戶音頻反饋一般是由無障礙服務TalkBack和系統觸摸浏覽功能提供。TalkBack無障礙服務會預置在大多數Android設備中,並且可以從GooglePlay免費下載。

4.5.1.1TalkBack測試

當用戶將焦點移到控件上,TalkBack無障礙服務會講述出用戶界面控件的內容。作為測試焦點導航和音頻提示的一部分,該服務應該被啟用。

啟用TalkBack無障礙服務:

1. 打開“設置”應用;

2. 導航到“無障礙”目錄並選擇它;

3. 選擇“無障礙”並啟用它;

4. 選擇“TalkBack”並啟用它;

注意:TalkBack是殘障用戶可用性最高的Android無障礙服務,其他無障礙服務也可獲得,並且可由用戶安裝。

4.5.1.2 觸摸浏覽測試

觸摸浏覽系統功能在Android4.0和以後版本的設備可獲得,啟用一個特殊無障礙模式,允許用戶在應用界面上拖動手指並聽取屏幕內容的讀出。該功能不需要使用定向控制器就可聚焦屏幕元素,並聽取用戶界面控件上的懸停事件。

啟用觸摸浏覽:

1. 打開“設置”應用;

2. 導航到“無障礙”目錄並選擇它;

3. 選擇“TalkBack”並啟用它;

注意:在Android4.1(API級別16)和更高版本的設備中,系統提供一個彈出消息啟用觸摸浏覽。在老版本中,必須遵守以下步驟。

4. 返回“無障礙”目錄,選擇觸摸浏覽並啟用它。

注意:必須先打開TalkBack,否則不會出現該選項。

4.5.2 測試焦點導航

焦點導航是為了操作應用中的獨立用戶界面元素,使用定向控制器在獨立用戶界面元素間導航。視覺障礙用戶或精細動作障礙用戶經常使用這種導航模式,代替觸摸導航。作為無障礙測試一部分,應該驗證應用可以在只使用定向控制的情況下進行操作。

可以使用純焦點控制測試應用的導航,即使要測試的設備沒有定向控制器。Android模擬器提供模擬定向控制器,可以用來測試導航。也可以使用基於軟件的定向控制器,例如,在一個沒有物理D-pad的測試設備上,由非視覺鍵盤提供一個定向控制器模擬D-pad的使用。

4.5.3 測試手勢導航

手勢導航是一個無障礙導航模式,允許用戶使用特定手勢導航Android設備和應用。該導航模式在Android4.1(API級別16)和更高版本中可獲得。

注意:無障礙手勢提供不同於鍵盤和D-pad的導航路徑。手勢允許用戶聚焦屏幕上幾乎所有的內容,鍵盤和D-pad導航只允許聚焦輸入區域和按鈕。

啟用手勢導航:

l啟用TalkBack和觸摸浏覽功能,被描述在“測試觸摸浏覽”。當啟用了這兩個功能,無障礙手勢自動啟動。

l可以在“設置>無障礙>TalkBack>設置>管理快捷手勢”中改變手勢設置。

更多關於使用觸摸浏覽無障礙功能的信息,詳見觸摸浏覽。

注意:無障礙服務,除TalkBack外,一個無障礙手勢可能映射不同的用戶操作。如果在測試過程中,手勢沒有產生預期結果,嘗試在繼續前關閉其他無障礙服務。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved