溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

AccessibilityService的使用

發(fā)布時間:2020-07-19 15:53:18 來源:網(wǎng)絡(luò) 閱讀:4378 作者:linwg1988 欄目:移動開發(fā)

最近使用AccessibilityService完成業(yè)務(wù),感覺還是蠻有意思的,順手寫一下這個類的用法,將來要是再有需要用到的時候也比較方便復(fù)習查閱。

AccessibilityService是用于開發(fā)無障礙功能應(yīng)用的api類,幫助殘障人士使用app。同樣的,使用它可以幫助我們對用戶體驗進行提升,例如手機助手中的一鍵安裝,免去了我們多次點擊的麻煩,它還能幫助我們完成一些看似外掛般的插件,比如搶紅包插件。

如何使用AccessibilityService:

首先,創(chuàng)建子類繼承AccessibilityService,AccessibilityService是服務(wù)的一種,那么我們需要在Mainifest注冊,同時添加相對應(yīng)的權(quán)限和過濾條件如下圖。

<service
   android:name="packagename.YourAccessibilityService"
   android:enabled="true"
   android:exported="true"
   android:label="@string/app_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/rob_service_config" />
</service>

AccessibilityService可以在xml中配置它的輔助信息即

<meta-data
       android:name="android.accessibilityservice"
       android:resource="@xml/rob_service_config" />

我們需要在res文件夾中增加對應(yīng)的xml文件res--xml--rob_service_config.xml,內(nèi)容如下

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
   android:accessibilityEventTypes="typeAllMask"
   android:accessibilityFeedbackType="feedbackSpoken"
   android:description="@string/accessibility_service_description"
   android:accessibilityFlags="flagDefault"
   android:canRetrieveWindowContent="true"
   android:notificationTimeout="100"
   android:packageNames="package_name_1,package_name_2" />

eventTypes代表該服務(wù)關(guān)注的事件類型,例如:

typeNotificationStateChanged  通知欄狀態(tài)改變
typeViewClicked               點擊事件
typeWindowStateChanged        窗體狀態(tài)變化
typeAllMask                   攔截所有的事件

等等等,這里我們可以根據(jù)我們的需求去選擇攔截類型。

packageNames即我們想要監(jiān)聽的應(yīng)用包名,可以監(jiān)聽多個應(yīng)用,包名之間以","隔開。

同樣的我們可以在代碼中配置這些信息:

    @Override
   public void onCreate() {
       super.onCreate();
//      AccessibilityServiceInfo info = new AccessibilityServiceInfo();
//      info.packageNames = installPackge; //監(jiān)聽過濾的包名
//      info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; //監(jiān)聽哪些行為
//      info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN; //反饋
//      info.notificationTimeout = 100; //通知的時間
//      setServiceInfo(info);
   }

做完這些以后,開啟服務(wù),打開設(shè)置中的輔助選項,選擇你的輔助服務(wù)并開啟,你就可以享受攔截其他app各種操作的快感了~那么,攔截到的事件在什么地方呢,AccessibilityService是一個抽象類,它的核心方法就是他的抽象方法

public abstract void onAccessibilityEvent(AccessibilityEvent event);

這個event就是我們攔截到的事件,這個方法是異步執(zhí)行的(當然了,萬一這事件被攔截并處理了半天,人家的app還讓不讓人用了),這個時間有view中的accessibilityDelegate對象發(fā)出。

好了,事件拿到了,就能對里面的內(nèi)容大做文章了,AccessibilityEvent最重要的就是它的eventType了,

/**
* Gets the event type.
*
* @return The event type.
*/
public int getEventType() {
   return mEventType;
}

畢竟我們需要知道這是什么類型時間才好繼續(xù)往下做嘛,然后就是

String className = event.getClassName().toString()

因為監(jiān)聽的是別人家的app,我們不知道我們想要知道的頁面類名是什么,所以想要在指定頁面做指定事情那就需要這個頁面的類名,有了這個方法,你還會不知道別人家的活動頁面的類名叫什么了嗎?

接下來就是getSource了獲取事件的節(jié)點信息,又或者我們可以使用

/**
* Gets the root node in the currently active window if this service
* can retrieve window content. The active window is the one that the user
* is currently touching or the window with input focus, if the user is not
* touching any window.
* <p>
* <strong>Note:</strong> In order to access the root node your service has
* to declare the capability to retrieve window content by setting the
* {@link android.R.styleable#AccessibilityService_canRetrieveWindowContent}
* property in its meta-data. For details refer to {@link #SERVICE_META_DATA}.
* </p>
*
* @return The root node if this service can retrieve window content.
*/
public AccessibilityNodeInfo getRootInActiveWindow() {
   return AccessibilityInteractionClient.getInstance().getRootInActiveWindow(mConnectionId);
}

獲取該事件觸發(fā)時的活動窗口,從這個活動窗口拿到我們想要的信息,比如包含某文字的控件,或者執(zhí)行想要做的輔助事件,比如點擊、滾動等。AccessibilityNodeIfo對象包含了樹狀父子節(jié)點信息,

public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewId(String viewId){...}
public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String text){...}

這兩個方法可以找到包含某文字或者某控件id名稱的節(jié)點

public boolean performAction(int action) {...}
public boolean performAction(int action, Bundle arguments){...}

這兩個方法可以使該節(jié)點執(zhí)行某個動作比如

AccessibilityNodeInfoA.CTION_CLICK

此外對于部分action,可以攜帶額外的參數(shù)

Bundle bundle = new Bundle();
bundle.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT,0);
bundle.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT,1);
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SET_SELECTION,bundle);

此外AccessibilityService本身有一個方法

* @see #GLOBAL_ACTION_BACK
* @see #GLOBAL_ACTION_HOME
* @see #GLOBAL_ACTION_NOTIFICATIONS
* @see #GLOBAL_ACTION_RECENTS
*/
public final boolean performGlobalAction(int action)

讓我們?nèi)?zhí)行全局的動作,如回退,返回home頁等。



AccessibilityService的使用大體就是這樣了,至于再詳細的東西就一個個的去文檔中找,并一個個使用它們吧。


此外,再記一下使用AccessibilityService過程中用到的tool

一個是D:\Users\XXX\Android\sdk\build-tools\23.0.0目錄下的aapt.exe
使用cmd切換到aapt目錄執(zhí)行aapt dump badging <file_path.apk>可以查看指定apk的包名等詳細內(nèi)容;

aapt使用小結(jié)   這里有十分詳細的介紹,對于這里來說,我們只需要知道目標應(yīng)用的包名即可;

另一個是D:\Users\XXX\Android\sdk\tools目錄下的uiautomatorviewer.bat

打開此文件連接手機,點擊工具的截屏按鈕,稍后你就能看到該頁面的布局層次以及各控件的信息(有我AccessibilityService需要的resId,這樣媽媽在不用擔心我找不到想要的那個nodeInfo了)。


Ok,this is the end.



向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI