Android AccessibilityService(輔助服務)學習

許多Android使用者因爲各種情況導致他們要以不同的方式與手機交互。這包括了有些用戶由於視力上,身體上,年齡上的問題致使他們不能看完整的屏幕或者使用觸屏,也包括了無法很好接收到語音信息和提示的聽力能力比較弱的用戶。Android提供了Accessibility功能和服務幫助這些用戶更加簡單地操作設備,包括文字轉語音,觸覺反饋,手勢操作,軌跡球和手柄操作。本文學習的是AccessibilityService(輔助服務)的使用。

類結構

public abstract class AccessibilityService extends Service

 

java.lang.Object

android.content.Context

        android.content.ContextWrapper

               android.app.Service

                          android.accessibilityservice.AccessibilityService


1.創建一個Android項目,創建一個服務類,繼承AccessibilityService

package com.example.accessibilityservice;

import android.accessibilityservice.AccessibilityService;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;

public class MyAccessibilityService extends AccessibilityService {
	private static final String TAG = "MyAccessibilityService";

	@Override
	protected void onServiceConnected() {
		Log.i(TAG, "onServiceConnected");
	}

	@Override
	public void onAccessibilityEvent(AccessibilityEvent event) {
		// TODO Auto-generated method stub
		Log.i(TAG, " eventType " + event.getEventType());
	}

	@Override
	public void onInterrupt() {
		// TODO Auto-generated method stub
		Log.i(TAG, "onServiceConnected");
	}

}


一個輔助性服務必須繼承AccessibilityService類,並且重寫這個類中下面的方法。這些方法由Android系統按順序調用的,當服務開啓時 (onServiceConnected()),當服務運行時(onAccessibilityEvent(), onInterrupt()) ,當服務結束時 (onUnbind())。
  • onServiceConnected()-(可選)當應用成功連接到你的輔助性服務時,系統調用該方法。使用這個方法爲你的輔助性服務做任何一次性設置的步驟,包括連接到用戶反饋的系統服務,如音頻管理器或設備振動器。一些初始化的操作放在這裏面。設置-輔助功能-打開輔助功能服務-確定之後會調用該方法。本Demo初始化參數是設置在AndroidManifest.xml裏面,所以這裏只添加打印爲了方便追蹤。如果你想在運行時或者一次性調整你服務的配置,這是一個方便的位置,這種情況時調用setServiceInfo()。
  • onAccessibilityEvent()-(必需)在用戶操作的過程中,系統不斷的發送sendAccessibiltyEvent(AccessibilityEvent event);然後通過onAccessibilityEvent()可以捕捉到該事件,當系統檢測到一個匹配你輔助性服務過濾器中設置參數的AccessibilityEvent時,調用該方法。例如,當用戶在一個應用程序中點擊一個按鈕或焦點放在用戶界面控件上時,,你的輔助性性服務就可以提供反饋。這種情況下,系統就通過相關連的AccessibilityEvent調用這個方法,然後服務就可以解釋和使用爲用戶提供的反饋了。這個方法在服務的生命週期中可能會被多次調用。
  • onInterrupt()-(必需)打斷獲取事件的過程,當系統中斷在你的服務中提供的反饋時調用該方法,通常是在響應用戶的諸如移動焦點到不同的控件上的動作時,調用該方法。該方法在你服務的生命週期中被多次的調用。
  • onUnbind()-(可選)當系統即將關閉當前輔助性服務時,調用該方法。使用這個方法來一次性關閉任何程序,包括釋放用戶反饋系統服務,如音頻管理器或設備振動器。

2. AndroidManifest.xml配置文件

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.accessibilityservice" >
    <uses-sdk android:minSdkVersion="18"
              android:targetSdkVersion="22"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        
        <service
            android:name="com.example.accessibilityservice.MyAccessibilityService"
            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>
    </application>

</manifest>

和其他服務一樣在AndroidManifest.xml中被聲明但它必須被指定操縱“android.accessibilityservice.AccessibilityService”的意圖


3. 其中的android:resource="@xml/accessible_service_config"配置

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/app_name"
    android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:packageNames="com.tencent.mm"
    android:notificationTimeout="10"
    android:accessibilityFlags=""
    android:canRetrieveWindowContent="true"/>
這裏需要提醒的是配置的時候packageNames這個就是你要監聽的包名,這裏我們需要監聽的是安裝的信息,所以包名就是com.tecent.mm,可以有多個用逗號隔開,accessibilityEventTypes這個是監聽的事件。

如果AndroidManifest.xml中沒有如上配置,則可以用java代碼在onServiceConnected中動態設置這些參數。

因爲本Demo沒有界面,如果安裝成功,不會啓動界面,只會在設置-輔助功能 中看到有對應的服務,服務名就是AndroidManifest.xml中定義的app_name



onAccessibilityEvent

這裏面最重要的部分就是onAccessibilityEvent這個回調函數,當我們註冊了監聽事件的時候,當有事件發生就會通知我們這個函數,但是一定要注意這個函數通知是異步的,當然很多朋友就會問這個是怎麼通知到這裏來的呢?他是通過AccessibilityDelegate這個代理類,發送出來的,這個類有個方法sendAccessibilityEvent可以發送事件。那這個類又怎麼和我們的窗口聯繫呢?這裏舉個例子。比如我們的View類裏面有個setAccessibilityDelegate這個方法,是不是這下一切都明瞭了呢?然後就是調用我們的find函數去當前節點裏面找到我們需要的節點信息,通過模擬點擊事件來安裝我們的軟件,當然如果是輸入框也是可以模擬輸入的哦。

拓展:onAccessibilityEvent方法中調用 AccessibilityNodeInfo noteInfo = event.getSource()可以獲得AccessibilityNodeInfo對象,進而可以做很多自動化相關的操作,比如批量安裝功能微信自動搶紅包自動化測試控件信息獲取等輔助性服務。


參考資料 http://www.xuebuyuan.com/2061595.html

更多詳細的可以參見官方文檔,或者Android SDK的samples裏的例子:ClockBackService, TaskBackService


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