android_他のデベロッパが開発したアプリ_UIの操作を自動化02

androidアプリの作成についてお尋ねします


Accessibility APIを使って

自作のアプリから

他のデベロッパが開発したアプリ内のUIの

操作を自動化したい場合、


対象のアプリのソースコードがない状態だと、

Accessibilityのためのヒントとなる

UIのxmlに定義されている属性の値が

わからない場合もあると思うのですが、


そのような場合はデバイスの画面内のどのボタンをタップしたいか、

などは、画面の座標をもとに指定するのでしょうか?



Accessibility API を使って 

**他のアプリの UI の操作を自動化** する場合、

対象アプリのソースコードがなくても、

画面上の UI 要素を特定する方法はいくつかあります。



## **1. UI 要素の特定方法**

対象のアプリの UI を特定するために、以下の方法を利用できます。


### **(1) AccessibilityNodeInfo を使う**


Accessibility API では、

画面内の UI 要素を **AccessibilityNodeInfo** として取得できます。

  

このオブジェクトを調べることで、

ボタンやテキストフィールドなどの情報

(ID、クラス名、テキストなど)を取得可能です。



#### **対象の UI 要素を特定する方法**


- **View ID(リソース ID)**


- **テキスト(ボタンのラベルなど)**


- **クラス名(`android.widget.Button` など)**


- **階層構造(親子関係をたどる)**



#### **コード例: 特定のボタンを探す**


```kotlin

override fun onAccessibilityEvent(event: AccessibilityEvent?) {


    if (event?.eventType

== AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {

        val rootNode = rootInActiveWindow ?: return

// "OK" というラベルのボタンを探す

        findAndClickButton(rootNode, "OK")  

    }

}


private fun findAndClickButton(

node: AccessibilityNodeInfo, buttonText: String) {


    if (node.className== "android.widget.Button"

&& node.text == buttonText) {

// ボタンをクリック

        node.performAction(

AccessibilityNodeInfo.ACTION_CLICK) 

        

return

    }

    for (i in 0 until node.childCount) {

        findAndClickButton(node.getChild(i), buttonText)

    }

}


```


この方法なら、

 **画面上の座標を指定しなくても、

 ボタンのテキストや ID で直接特定** できます。


---


### **(2) Hierarchy Viewer / uiautomatorviewer を使う**


Android SDK のツール **uiautomatorviewer** や 

**Hierarchy Viewer** を使えば、

**対象アプリの UI ツリーを調査** できます。



#### **手順**

1. **`uiautomatorviewer` を起動**


   ```

   cd $ANDROID_HOME/tools/bin

   ./uiautomatorviewer

   

   ```

   

   

2. **スクリーンショットを取得**


3. **画面上のボタンやテキストフィールドの ID を確認**


この方法で、ターゲットアプリの UI の **ID やクラス名を特定** できます。


---


### **(3) 画面座標を直接指定する(最終手段)**


対象アプリの UI 情報が取得できない場合、 

**画面座標を指定してタップする方法** もあります。  


ただし、この方法は **画面サイズやレイアウト変更の影響を受ける** ため、

可能な限り **AccessibilityNodeInfo 

を使う方法を優先** するべきです。



#### **コード例: 指定座標をタップ**


```kotlin


val path = Path()

path.moveTo(500f, 1000f) // タップしたい座標

val gestureDescription = GestureDescription.Builder()


    .addStroke(

GestureDescription.StrokeDescription(path, 0, 100))

    .build()

dispatchGesture(

gestureDescription, null, null)


```



この方法では、

**特定の座標をタップできますが

、画面レイアウトが変わると正しく動作しなくなる** 

というリスクがあります。



---



## **2. 結論**

### **❌ 非推奨:画面座標でタップ**

- 画面のサイズや UI が変わると使えなくなる

- **座標指定は最終手段として考える**


### **✅ 推奨:AccessibilityNodeInfo で UI を特定**

- **ボタンのテキストや ID で特定し、タップ**

- `uiautomatorviewer` で UI 構造を確認し、正しい ID やクラス名を取得


---


### **補足:Google Play ポリシーの注意点**


他のアプリの UI を自動操作する場合、

**Google Play のポリシー違反になる可能性が高い** です。


特に、**ユーザーの許可なしに UI を自動操作すると、

アプリがストアから削除されるリスクがあります。**


もし Google Play に公開するアプリであれば、

**Accessibility API の利用が許可されるケース**

(視覚障がい者向けアプリなど)を満たしているかを確認してください。



---


### **まとめ**

| 方法 | メリット | デメリット |

|------|---------|-----------|

| **AccessibilityNodeInfo で ID やテキストを使う(推奨)** | UI の変化に強い | 使えないアプリもある |

| **uiautomatorviewer で ID を調査** | 事前に UI を調べられる | 対象アプリの UI に変更があると使えなくなる |

| **画面座標をタップ(非推奨)** | 特定の状況では有効 | 画面サイズやレイアウト変更の影響を受ける |



#### **→ 可能なら、`AccessibilityNodeInfo` を使って、

UI 要素を直接取得する方法を選びましょう。**




コメント