Android-Accessibility(輔助功能)

最近開(kāi)發(fā)用到了輔助功能,趕緊整理下來(lái)卸奉。先介紹一下Accessibility:
對(duì)于那些由于視力慰毅、聽(tīng)力或其它身體原因?qū)е虏荒芊奖闶褂肁ndroid智能手機(jī)的用戶德撬,Android提供了Accessibility功能和服務(wù)幫助這些用戶更加簡(jiǎn)單地操作設(shè)備,包括文字轉(zhuǎn)語(yǔ)音固歪、觸覺(jué)反饋蒜鸡、手勢(shì)操作胯努、軌跡球和手柄操作。開(kāi)發(fā)者可以搭建自己的Accessibility服務(wù)逢防,這可以加強(qiáng)可用性叶沛,例如聲音提示,物理反饋忘朝,和其他可選的操作模式灰署。
隨著Android版本的不斷升級(jí),Android Accessibility功能也越來(lái)越強(qiáng)大局嘁,Android 4.0版本以前溉箕,系統(tǒng)輔助服務(wù)功能比較單一,僅僅能過(guò)單向獲取窗口元素信息悦昵,比如獲取輸入框用戶輸入內(nèi)容肴茄。到Android 4.1版本以后,系統(tǒng)輔助服務(wù)增加了與窗口元素的雙向交互但指,此時(shí)可以通過(guò)輔助功能服務(wù)操作窗口元素寡痰,比如點(diǎn)擊按鈕等。
由于系統(tǒng)輔助服務(wù)能夠?qū)崟r(shí)獲取您當(dāng)前操作應(yīng)用的窗口元素信息棋凳,這有可能給你帶來(lái)隱私信息的泄露風(fēng)險(xiǎn)拦坠,比如獲取非密碼輸入框的輸入內(nèi)容等。同時(shí)通過(guò)輔助功能也可以模擬用戶自動(dòng)化點(diǎn)擊應(yīng)用內(nèi)元素剩岳,也會(huì)帶來(lái)一定的安全風(fēng)險(xiǎn)贞滨。

下面來(lái)實(shí)際操作一下(AndroidStudio)

1.在res文件下創(chuàng)建一個(gè)xml文件夾,在文件夾下創(chuàng)建一個(gè)phone_accessibilit.xml:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service android:description="@string/accessibility_service_description"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="100"
android:accessibilityFlags=""
android:canRetrieveWindowContent="true"
xmlns:android="http://schemas.android.com/apk/res/android" />
文件中定義了一些關(guān)于輔助功能服務(wù)的相關(guān)屬性

2.創(chuàng)建MyAccessibilityService

同時(shí)在manifest文件中填寫(xiě)service的相關(guān)信息卢肃。

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service
        android:name=".MyAccessibilityService"
        android:label="@string/acc_service_name"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>
        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/phone_accessibility" />
    </service>
</application>

MyAccessibilityService:

public class MyAccessibilityService extends AccessibilityService {
private static int ACTION_STEP = 0;

@Override
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
    try {
        processAccessibilityEnvent(accessibilityEvent);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void processAccessibilityEnvent(AccessibilityEvent event) {
    if (event.getSource() == null) {
        Log.d("accessibility", "null");
        return;  //如果event沒(méi)有內(nèi)容,直接返回.
    }

    Log.d("accessibility", event.getPackageName().toString());

    if (event.getPackageName().equals("com.mrtian.example.accessibilitytest")) {    //通過(guò)包名,分別處理
        //查找對(duì)應(yīng)id的View結(jié)點(diǎn)
        List<AccessibilityNodeInfo> nodes = event.getSource().findAccessibilityNodeInfosByViewId("com.mrtian.example.accessibilitytest:id/button_01");
        if (nodes != null && !nodes.isEmpty()) {
            Log.d("accessibility", "button1 :" + "click");
            AccessibilityNodeInfo node1;
            for (int i = 0; i < nodes.size(); i++) {
                node1 = nodes.get(i);
                if (node1.getClassName().equals("android.widget.Button") && node1.isEnabled()) {
                    //如果發(fā)現(xiàn)該結(jié)點(diǎn),做一個(gè)點(diǎn)擊操作
                    node1.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                }
            }
        }
        //通過(guò)id查找結(jié)點(diǎn)
        List<AccessibilityNodeInfo> list = event.getSource().findAccessibilityNodeInfosByViewId("com.qihoo.appstore:id/search_list_view");
        if (list != null && !list.isEmpty()) {
            //做一個(gè)下拉操作
            list.get(0).performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
        }

        //做一個(gè)下拉通知欄的操作
        //this.performGlobalAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS);

    }

}
@Override
public void onInterrupt() {

}

}
為了給出思路疲迂,我做了一個(gè)簡(jiǎn)單的演示,不停點(diǎn)擊界面中的一個(gè)button莫湘。button的數(shù)字不停增加。

開(kāi)啟輔助功能后郑气,程序就會(huì)不斷回調(diào)onAccessibilityEvent函數(shù)幅垮,參數(shù)AccessibilityEvent accessibilityEvent,accessibilityEvent.getSource可以得到整個(gè)頁(yè)面的信息尾组。

通過(guò)event.getPackageName()得到應(yīng)用程序的包名忙芒,可以判斷包名做出不同的操作。

event.getSource().findAccessibilityNodeInfosByViewId/ByText可以通過(guò)文本或者id找到相應(yīng)的控件結(jié)點(diǎn)讳侨,拿到結(jié)點(diǎn)以后就可以做一些操作呵萨,比如點(diǎn)擊、下拉跨跨、觸摸...返回值是一個(gè)AccessibilityNodeInfo的list潮峦,AccessibilityNodeInfo是結(jié)點(diǎn)信息囱皿,對(duì)應(yīng)方法getParent,getChildren可以得到父子結(jié)點(diǎn)。

有了這個(gè)就可以做很多事情忱嘹,建議:

1.可以設(shè)置一個(gè)靜態(tài)變量來(lái)控制操作的步驟嘱腥。
2.利用DDMS可以查看當(dāng)當(dāng)前布局樹(shù),可以查看每個(gè)結(jié)點(diǎn)的id拘悦、Text齿兔、clickable等屬性。
3.利用Handler的postDelayed來(lái)做一些延時(shí)操作础米。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末分苇,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子屁桑,更是在濱河造成了極大的恐慌组砚,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掏颊,死亡現(xiàn)場(chǎng)離奇詭異糟红,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)乌叶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)盆偿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人准浴,你說(shuō)我怎么就攤上這事事扭。” “怎么了乐横?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵求橄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我葡公,道長(zhǎng)罐农,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任催什,我火速辦了婚禮涵亏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蒲凶。我一直安慰自己气筋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布旋圆。 她就那樣靜靜地躺著宠默,像睡著了一般。 火紅的嫁衣襯著肌膚如雪灵巧。 梳的紋絲不亂的頭發(fā)上搀矫,一...
    開(kāi)封第一講書(shū)人閱讀 51,198評(píng)論 1 299
  • 那天抹沪,我揣著相機(jī)與錄音,去河邊找鬼艾君。 笑死采够,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的冰垄。 我是一名探鬼主播蹬癌,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼虹茶!你這毒婦竟也來(lái)了逝薪?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蝴罪,失蹤者是張志新(化名)和其女友劉穎董济,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體要门,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虏肾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了欢搜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片封豪。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖炒瘟,靈堂內(nèi)的尸體忽然破棺而出吹埠,到底是詐尸還是另有隱情,我是刑警寧澤疮装,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布缘琅,位于F島的核電站,受9級(jí)特大地震影響廓推,放射性物質(zhì)發(fā)生泄漏刷袍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一受啥、第九天 我趴在偏房一處隱蔽的房頂上張望做个。 院中可真熱鬧,春花似錦滚局、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至糯景,卻和暖如春嘁圈,著一層夾襖步出監(jiān)牢的瞬間省骂,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工最住, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钞澳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓涨缚,卻偏偏與公主長(zhǎng)得像轧粟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子脓魏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容