Android AccessibilityService實現第三方APP行爲捕獲

Android AccessibilityService實現第三方APP行爲捕獲

 

五號先生丶關注

https://www.jianshu.com/p/d3cf94ef1eb6

0.1012018.12.07 13:46:59字數 1,146閱讀 1,107

AccessibilityService實現行爲捕獲

語音:Kotlin            版本:1.2.41
最近接到一個很奇葩的需求:捕獲系統語音通話聊天(包括微信、電話、QQ),把通話內容記錄成音頻文件上傳到服務端。
接到需求的第一時間當然是度娘谷歌一陣,一頓亂搜之後發現並沒有太多能夠用來參考的文獻。
沒有現成的輪子可用,只能擼起袖子,自己動手豐衣足食。

AccessibilityService簡介

AccessibilityService中文翻譯爲輔助服務,它能夠幫助我們獲取第三方應用的操作信息。
AccessibilityService的所帶來的安全隱患在這裏不多贅述,主要介紹一些關於它的特性和用法。
本文章將用大家常用的微信來舉例,獲取微信語音通話界面的控件佈局,提取到關鍵常量之後,用AccessibilityService來捕獲。
先來看一段官方對AccessibilityService的描述:

Accessibility services should only be used to assist users with disabilities in using Android devices and apps. They run in the background and receive callbacks by the system when AccessibilityEvents are fired. Such events denote some state transition in the user interface, for example, the focus has changed, a button has been clicked, etc. Such a service can optionally request the capability for querying the content of the active window. Development of an accessibility service requires extending this class and implementing its abstract methods.

Lifecycle

The lifecycle of an accessibility service is managed exclusively by the system and follows the established service life cycle. Starting an accessibility service is triggered exclusively by the user explicitly turning the service on in device settings. After the system binds to a service, it calls onServiceConnected(). This method can be overridden by clients that want to perform post binding setup.

An accessibility service stops either when the user turns it off in device settings or when it calls disableSelf().

從描述中我們可以得到如下幾個信息:

1.AccessibilityService只能用於幫助殘障人士使用Android設備和應用;

2.運行在後臺,可以實現無感知運作;

3.能夠監測焦點的切換、點擊等事件;

4.APP只能對其進行註冊,無法自動開啓;

5.啓動AccessibilityService需要用戶進入“設置-無障礙”手動開啓,關閉亦是如此。

放上官方文檔的鏈接(需爬梯):
https://developer.android.com/reference/android/accessibilityservice/AccessibilityService

 

AccessibilityService基本配置方式

創建MyAccessibilityService繼承AccessibilityService

覆寫onServiceConnected、onAccessibilityEvent、onInterrupt方法。

三個方法分別爲AccessibilityService的三個生命週期。

可以大致理解爲“服務啓動時”、“服務監聽中”、“斷開服務”

/*
 * Create by parker
 * Author: parker
 * Create: 2018/12/7 10:48 AM
 *
 */
class MyAccessibilityService : AccessibilityService() {

    override fun onServiceConnected() {
        super.onServiceConnected()
    }

    override fun onAccessibilityEvent(event: AccessibilityEvent) {

    }

    override fun onInterrupt() {

    }
}

在AndroidManifest.xml中註冊:

    <service
        android:name=".MyAccessibilityService"
        android:enabled="true"
        android:exported="false"
        android:label="@string/my_as"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
        android:process=":BackgroundService">
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>
        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibility_config" />
    </service>

在res下新建accessibility_config.xml文件:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:canRetrieveWindowContent="true"
    android:notificationTimeout="100"
    android:description="@string/description"
    android:packageNames="com.tencent.mm" />

屬性作用如下:

android:description :輔助功能描述,描述該輔助功能用來幹嘛的
android:packageNames :指定輔助功能監聽的包名,不指定表示監聽所有應用
android:accessibilityEventTypes:輔助功能處理事件類型,一般配置爲typeAllMask表示接收所有事件
android:accessibilityFlags:輔助功能查找截點方式,一般配置爲flagDefault默認方式。
android:accessibilityFeedbackType:操作相應按鈕以後輔助功能給用戶的反饋類型,包括聲音,震動等。
android:notificationTimeout:相應時間設置
android:canRetrieveWindowContent:是否允許輔助功能獲得窗口的節點信息,爲了能正常實用輔助功能,請務必保持該項配置爲true

配置完成後將demo跑進測試機器

進入 設置→輔助服務→無障礙

如果在“無障礙”下出現我們配置的服務,表示配置成功

 

實現微信語音電話狀態監聽

監聽工作流程如下:
·捕獲微信進入聊天狀態
·啓動語音錄製服務
·捕獲微信退出聊天狀態
·退出語音錄製服務

首先需要藉助工具來分析微信的佈局。通過捕獲微信佈局中的關鍵常量,來判斷微信當前的狀態。

佈局分析工具

谷歌在AS 3.0之後,取消老舊的DDMS,爲我們提供了界面更爲友好的全新工具:LayoutInspector

打開方式:Tools → Lyaout Inspector 如圖:

屏幕快照 2018-12-07 上午11.37.37.png

點擊之後,系統彈出Choose Porcess提示我們選擇需要監聽的進程,這裏我們選擇微信,先不要點“OK”:

屏幕快照 2018-12-07 下午1.28.41.png

在微信上啓動語音聊天,然後點擊Choose Process的OK,選擇VideoActivity,如圖:

屏幕快照 2018-12-07 下午1.30.13.png

捕獲到的微信聊天界面的佈局如圖所示:

屏幕快照 2018-12-07 下午1.33.05.png

通過分析左邊的View Tree我們發現,微信中提示已接通、通話結束等狀態的控件id爲eg7.
這是一個很有用的發現,它的文本內容可以直接作爲判斷微信通話是否連接或者斷開的依據。


ok 知道了微信語音聊天了開始和結束的狀態判定依據,接下來就是用代碼來實現監聽的過程。

核心代碼如下:

override fun onAccessibilityEvent(event: AccessibilityEvent){
    //獲取當前界面的佈局信息
    val noteInfo: AccessibilityNodeInfo = when {
        rootInActiveWindow != null -> rootInActiveWindow
        event.source != null -> event.source
        else -> return
    }

    //獲取id爲eg7的控件  並根據內容執行相應的操作
    val wechatToast = noteInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/eg7")
    //如果id爲eg7的控件存在
    if (wechatToast.size>0){
        //判斷這個控件的內容
        if (wechatToast[0].text.toString() == "已接通"){
            //此時語音聊天已經接通
            //TODO:do something you want
        }else if (wechatToast[0].text.toString().contains("聊天結束")){
            //此時語音聊天已經結束
            //TODO:do something you want
        }
    }
}

至此,微信聊天狀態已經捕獲完成,TODO處可實現語音錄製相關代碼。
語音錄製過程會在下一篇文章中詳細介紹。

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