Accessibility輔助控制類


熟悉Android開發的都知道輔助功能服務 Accessibility service。他的作用有很多,360豌豆莢等應用市場的非root自動安裝,微信搶紅包插件,盲人輔助程序等等功能都是靠它實現的。 網上關於AccessibilityService的闡述和用法已經很多很詳細了,能翻牆且英文沒問題就直接看官網:http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html這裏介紹個模擬自動點擊事件的流程。

附上demo: https://github.com/jackuhan/WeChatLuckyMoney

我們寫一個繼承自AccessibilityService的XXXService類,在manifest中註冊下

<service
                android:name=".XXXService"
                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/accessible_service_config"/>
        </service>


這裏註冊了響應AccessibilityService 的intent-filter,那麼這個service可以在系統觸發AccessibilityEvent的時候被回調到。這個時候你的service此時會響應所有應用的同類Event,如果想只響應某個特殊應用就需要使用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;
    info.notificationTimeout = 100;
    this.setServiceInfo(info);
}



在程序中判斷有沒有開啓這個自動點擊服務。

AccessibilityManager accessibilityManager = (AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
        List<AccessibilityServiceInfo> accessibilityServices = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC);
        for (AccessibilityServiceInfo info : accessibilityServices) {
            if (info.getId().equals(getPackageName() + "/.XXXService")) {
                //開啓了服務
            }
        }


如果沒有開啓,那麼打開系統設置頁面,用戶點擊開啓。

Intent mAccessibleIntent =  new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(mAccessibleIntent);




AccessibilityService有以下幾個回調

public void onAccessibilityEvent(AccessibilityEvent event);
        public void onInterrupt();
        public void onServiceConnected();
        public void init(int connectionId, IBinder windowToken);
        public boolean onGesture(int gestureId);
        public boolean onKeyEvent(KeyEvent event);


onServiceConnected ()方法是AccessibilityService聲明週期的一部分,在系統成功與服務綁定後才被呼叫,如果用來設定AccessibilityServiceInfo.這個方法更爲方便。


這裏需要在onAccessibilityEvent的回調中得到AccessibilityEvent ,

通過AccessibilityEvent.getSource()方法能夠從資源中獲得窗口的內容和行爲,AccessibilityNodeInfo。通過findAccessibilityNodeInfosByViewId()或者findAccessibilityNodeInfosByText()方法可以確定我們要點擊的按鈕;

,然後performAction  ACTION_CLICK即可就完成了點擊名稱爲"Name"的控件的事件了。


onAccessibilityEvent(AccessibilityEvent event)  {
AccessibilityNodeInfo nodeInfo = event.getSource()
List<AccessibilityNodeInfo> fetchNodes = nodeInfo.findAccessibilityNodeInfosByText("Name");
AccessibilityNodeInfo openNode = fetchNodes.get(int i);
openNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}



Android 4.0版本中增加了一個新特性,就是能夠用AccessibilityService來遍歷View層級,並從產生Accessibility 事件的組件與它的父子組件中提取必要的信息。爲了實現這個目的,你需要配置:android:canRetrieveWindowContent="true"。同時Android 4.0版本開始,可以使用XML文件來配置這類service。

格式如下所示:

<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配置service的方式,確保在manifest中聲明 <meta-data>這個標籤內容,指定該service保存在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>




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章