AccessibilityService(バリアフリーサポート)


アクセスの詳細
1、サービスの作成
独自のサービスクラスを作成するには、AccessibilityServiceクラスを継承する必要がある.その中で実現するonAccessibilityEvent(AccessibilityEvent event)およびonInterruput()2つの重要な方法:
public class RobService extends AccessibilityService {

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {   }

    @Override
    public void onInterrupt() {  }
}
   

ここでは、このクラスでよく使われる方法について説明します.詳細は公式ドキュメントを参照してください.
方法
さぎょうdisableSelf()
現在のサービスを無効にします.つまり、サービスがこの方法で停止できる場合です.findFoucs(int falg)
特定のフォーカスタイプを持つコントロールの検索getRootInActiveWindow()
ウィンドウの内容を取得できるように設定すると、現在のアクティブなウィンドウのルートノードが返されます.getSeviceInfo()
現在のサービスの構成情報の取得onAccessibilityEvent(AccessibilityEvent event )
AccessibilityEventイベントに関するコールバック関数.システムはsendAccessibiliyEvent()を介してアクセスibilityEventをここに絶えず送信するperformGlobalAction(int action)
戻る、ホームページに戻る、最近開くなどのグローバル操作を実行します.setServiceInfo(AccessibilityServiceInfo info)
現在のサービスの構成情報の設定getSystemService(String name)
システムサービスの取得onKeyEvent(KeyEvent event)
サービスがキー操作を傍受することを許可する場合、この方法はキーイベントのコールバックであり、このプロセスがシステムがキーイベントを処理する前にonServiceConnected()
システムがサービスをバインドに成功したときにトリガーされます.つまり、設定で対応するサービスをオンにすると、システムがサービスをバインドに成功したときにトリガーされます.通常、ここで初期化操作を行うことができます.
2、生命サービス
他のサービスのようにAndroidManifestが必要です.xmlでこのサービスを宣言します.このほか、サービスは次の2つを構成する必要があります.
  • 配置、そのnameが固定されている:android.accessibilityservice.AccessibilityService
  • BIND_を宣言ACCESSIBILITY_SERVICE権限は、システムがサービスをバインドできるようにする(4.0以降の要求)
  • 注意:任意の構成エラーは、システムが反応しないため、固定構成は次のとおりです.
    
        
            
        
    

    3、パラメータ設定
    AndroidManifestでxmlがサービスを宣言すると、次はサービスにいくつかのパラメータ設定が必要になる.このサービスは、指定する種類のイベントを受け付ける、指定したpackageを傍受する、ウィンドウの内容を検索する、イベントの種類を取得する時間などを構成することができる.現在、2つの構成方法があります.
  • 方法1:4.0以降に提供されるラベルによる配置
  • 方法2:通過setServiceInfo()配置
  • 3.1. で配置する
    AndroidManifestでxmlライフのサービスにmeta-dataラベルを指定し、android:resourceで対応するプロファイルを指定します(resディレクトリの下でxmlファイルを作成し、プロファイルaccessibility.xmlを作成します):
     
        
            
            
        
        
        

    次にアクセスを見てみましょうxmlの関連構成:
    
    
    

    3.2通過setServiceInfo(AccessibilityServiceInfo info)また、setServiceInfo(AccessibilityServiceInfo)により構成情報を得ることができるほか、この方法により、実行中にサービス構成を動的に変更することができる.なお、この方法は動的プロパティの構成にのみ使用できます.eventTypes,feedbackType,flags,notificaionTimeout packageNames.通常はonServiceConnected()で構成され、以下のコードがあります.
    @Override
        protected void onServiceConnected() {
            AccessibilityServiceInfo serviceInfo = new AccessibilityServiceInfo();
            serviceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
            serviceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
            serviceInfo.packageNames = new String[]{"com.tencent.mm"}; 
            serviceInfo.notificationTimeout=100;
            setServiceInfo(serviceInfo);
        }
    accessibilityEventTypes:ウィンドウの開き、スライド、フォーカスの変化、長押など、どのようなイベント通知に興味があるかを示す.具体的な値はAccessibilityEventクラスで調べることができ、typeAllMaskがすべてのイベント通知を受け入れることを示す.accessibilityFeedbackType:フィードバック方式を示す、例えば音声再生か、振動かcanRetrieveWindowContent:当該サービスがアクティブウィンドウの内容にアクセスできるかを示す.すなわち、サービスでフォームのコンテンツを取得する場合は、その値をtrueに設定する必要がある.notificationTimeout:イベントを受け取る間隔は、通常100に設定すればよい.packageNames:当該サービスがどのパケットの発生を傍受するためのイベントであるかを示す
    4、サービスを開始する
    以上の操作を完了すると、アプリを携帯電話にインストールすることができます.インストールに成功すると、セットアップ->アシスト機能で私たちのサービスを見つけることができます.このサービスはデフォルトではクローズ状態であり、手動で開く必要がある.
    5、イベント情報の取得
    前述したように、onAccessibilityEvent(AccessibilityEvent event)は、パラメータeventがインタフェース関連イベントからの情報をカプセル化するサービスの核心的な方法であり、例えば、イベントのイベントタイプを取得し、タイプに応じて異なる処理方法を選択することができる.
    public void onAccessibilityEvent(AccessibilityEvent event) {
            int eventType = event.getEventType();
            switch (eventType) {
                case AccessibilityEvent.TYPE_VIEW_CLICKED:
                    //    
                    break;
                case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
                    //      
                    break;
            }
        }

    ここでは、AccessibilityEventについて簡単に説明します.ユーザーが変化すると、ボタンがクリックされるとTYPE_が送信されるなど、一連のAccessibilityEventイベントが送信されます.VIEW_CLICKEDタイプのイベント
    方法
    説明getEventType()
    イベントのタイプgetSource()
    イベントソースに対応するノード情報の取得getClassName()
    イベントソース対応クラスのタイプを取得します.たとえば、クリックイベントがButtonによって生成された場合、このとき取得されるのはButtonの完全なクラス名です.getText()
    イベントソースのテキスト情報を取得する、例えば、イベントにTextViewが発行する、このとき取得するのがTextViewのtext属性である.イベントソースがツリー構造である場合、このツリー上のtext属性を持つすべての値のセットが取得されます.isEnabled()
    イベントソース(対応するインタフェースコントロール)が使用可能かどうかgetItemCount()
    イベントソースがツリー構造の場合、ルートノードのサブノードの数が返されます.
    システムは絶えず各種の事件を発生して、一部はインタフェースのコントロールが発生して、一部はシステムが発生したのです.インタフェースコントロールによって生じるイベントについては、通常、このコントロールをイベントソースと呼ぶ.すべてのイベントがgetSource()メソッドでイベントソースを取得できるわけではない、例えば通知メッセージタイプのイベント(TYPE_NOTIFICATION_STATE_CHANGED)である.
    6、ウィンドウの内容を取得する
    イベントの情報だけでは不十分であることを知るには、Buttonボタンがクリックされたときのtextのようなイベント(イベントソース)を発行する情報も取得したい.1つのサービスは、サービスがウィンドウのコンテンツを取得すること、すなわち、ウィンドウのコンテンツを取得することを可能にするように構成することができる.ウィンドウ全体の内容は本質的にAccessibilityWindowInfoとAccessibilityNodeInfoに関するツリー構造であり、私はコンテンツツリーと呼ぶ.(View Treeに似ていますが、全く同じではありません)
    本サービスは、全てのイベントではなく、一部のイベントのみを検出するように構成することができるので、コンテンツツリーが変化すると、本サービスが現在のコンテンツツリーが変化するか否かをタイムリーに知ることができないことを意味する.例えば、あなたのサービスはクリックイベントだけを検出しましたが、インタフェースの入力焦点が変化し、ノードツリー全体が変化しましたが、あなたのサービスは知りません.このとき、あなたがノードで手に入れたウィンドウの内容は最新ではないかもしれません.したがって、現在のウィンドウの内容をタイムリーに知りたい場合は、構成時にすべてのイベントをリスニングするように設定する.
    前述のように、ウィンドウの内容を取得するには、AccessibilityServiceの構成時にcanRetrieveWindowContentをtrueに設定する必要がある.その後、ウィンドウの内容を以下の方法で取得できます.AccessibilityEvent.getSource()findFocus(int)getWindow()またはgetRootInActiveWindow()7、サービスのライフサイクル
    このサービスのライフサイクルを理解するには、3つの点を覚えておく必要があります.
  • このサービスは完全にシステムによって管理する、既存のサービスサイクルに従う.
  • 1つのサービスを開くにはユーザのみが設定中に開くが、閉じるにはユーザのみが設定中に閉じるか、サービス自体がdiableSelf()メソッドで閉じる(もちろん、現在は第3のソフトウェアでも強制的にこのタイプのサービスを閉じることができる場合がある)
  • システムがサービスをバインドすると、onServiceConnected()メソッドが呼び出されます.このメソッドは書き換えられ、初期化された操作を行うことができます.

  • 8、サービスがオープンしているかどうかを検査する
    AccessibilityServiceの基礎知識をいくつか紹介した後、あるサービスが開いているかどうかを検出する知識を少し補充した.通常、サービスが有効かどうかを検出するには、次の2つの方法があります.
    方法1:サービスマネージャAccessibilityManagerで判断するが、この方法ではapp自体が開いているサービスを検出できない.
    private boolean enabled(String name) {
            AccessibilityManager am = (AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
            List serviceInfos = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC);
            List installedAccessibilityServiceList = am.getInstalledAccessibilityServiceList();
            for (AccessibilityServiceInfo info : installedAccessibilityServiceList) {
                Log.d("MainActivity", "all -->" + info.getId());
                if (name.equals(info.getId())) {
                    return true;
                }
            }
            return false;
        }

    AccessibilityManagerについて説明した以上、ここでは簡単な紹介をします.AccessibilityManagerはシステムレベルのサービスであり、イベントの配布、システム内のサービスのステータスの照会など、AccessibilityServiceサービスを管理するために使用されます.詳細は公式ドキュメントを参照してください.一般的な方法は次のとおりです.
    方法
    説明getAccessibilityServiceList()
    サービスリストの取得(api 14以降は廃棄し、以下の方法で代替)getInstalledAccessibilityServiceList()
    システムにインストールされているサービスのリストを取得getEnabledAccessibilityServiceList(int feedbackTypeFlags)
    有効なサービスリストの取得isEnabled()
    サービスが有効かどうかを判断するsendAccessibilityEvent(AccessibilityEvent event)
    イベントの送信
    方法2:wifi、Bluetooth状態など、ほとんどのシステム属性がsettingsで設定されていることを知っていますが、これらの情報は主にsettingsに対応するデータベース(systemテーブルとserureテーブル)に格納されています.これは、setting設定を直接読み取ることで、関連サービスがオープンしているかどうかを判断することができます.
    private boolean checkStealFeature1(String service) {
            int ok = 0;
            try {
                ok = Settings.Secure.getInt(getApplicationContext().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
            } catch (Settings.SettingNotFoundException e) {
            }
    
            TextUtils.SimpleStringSplitter ms = new TextUtils.SimpleStringSplitter(':');
            if (ok == 1) {
                String settingValue = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
                if (settingValue != null) {
                    ms.setString(settingValue);
                    while (ms.hasNext()) {
                        String accessibilityService = ms.next();
                        if (accessibilityService.equalsIgnoreCase(service)) {
                            return true;
                        }
    
                    }
                }

    実際の応用
    今までAccessibilityServiceに関するいくつかの知識は、私たちはすでに話しました.次に、その具体的な使用を見てみましょう.その中の典型的な応用はお年玉プラグインを奪うことです.