[環境構築] UbuntuでAppiumを使ってAndroidを制御する

# はじめに
とある事情によりPCからAndroidを自動操作したくなりました。
調べたところAppiumが良いらしいので、素人ながら導入メモを残します。

# 使用機器
- Thinkpad X230 (Ubuntu 22.04 LTS)
- Redmi Note 10 JE (Android 13)

# 環境構築
## USB Debug Mode
Android端末の開発者向けオプションを表示し、下記３つの機能を有効にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228338/ce1f9564-a1c9-8c5f-f574-347c0c0398e4.png)

## JDK
### Android studio用にJDK 11をインストール
```console
$ sudo apt install openjdk-11-jdk -y
$ java --version
openjdk 11.0.21 2023-10-17
OpenJDK Runtime Environment (build 11.0.21+9-post-Ubuntu-0ubuntu122.04)
OpenJDK 64-Bit Server VM (build 11.0.21+9-post-Ubuntu-0ubuntu122.04, mixed mode, sharing)
```

### UiAutomator2 Driver用にJDK 8をインストール
https://appium.io/docs/en/2.4/quickstart/uiauto2-driver/#java-jdk
> Install the Java JDK (for the most recent Android API levels, JDK 9 is required, otherwise JDK 8 is required). 

Appium公式によれば、最新のAndroidはJDK 9が必要。しかしJDK 9はaptでパッケージ化されていないので、インストールが面倒。ひとまずJDK 8をインストールすることにした。
```console
$ sudo apt install openjdk-8-jdk -y
$ java --version
openjdk 11.0.21 2023-10-17
OpenJDK Runtime Environment (build 11.0.21+9-post-Ubuntu-0ubuntu122.04)
OpenJDK 64-Bit Server VM (build 11.0.21+9-post-Ubuntu-0ubuntu122.04, mixed mode, sharing)
```
デフォルトのJDKバージョンは11にしておく。
```console
$ sudo update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                            Priority   Status
------------------------------------------------------------
* 0            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      auto mode
  1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      manual mode
  2            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1081      manual mode

Press <enter> to keep the current choice[*], or type selection number: 
```

## Node.js
Appiumの動作に必要（インストール済でした）。
```console
$ node --version
v20.11.0
```

## npm
Appiumのインストールに必要。
```console
$ sudo apt install npm -y
$ sudo npm install n -g
$ sudo n stable
$ node --version
v20.11.0
```

## Android Studio
https://developer.android.com/studio
android-studio-2023.1.1.28-linux.tar.gzをDL

```console
$ cd /usr/local/
$ sudo tar -zxvf ~/Downloads/android-studio-2023.1.1.28-linux.tar.g
```
64ビット版Ubuntuの場合、32ビット用のライブラリをインストール
```console
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386 -y
```

Android Studioの起動
```console
$ cd android-studio/bin/
$ ./studio.sh
```
設定そのままで"Next"を押していく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228338/215b6136-a229-2571-f771-e72f016d7ae0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228338/eee87ab1-82ee-fcf4-d155-a9dd56870413.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228338/581051fd-be4a-aa51-5db2-2d4da6b0cdbe.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228338/32f54f00-7d4c-f089-2b02-f66cb501fc21.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228338/345f303f-dc0c-2232-4acf-b5bc4bfa975d.png)

コンポーネントのDLを待つ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228338/afdd1815-5e10-1bfb-75ea-5e0d08445f5b.png)

"More Actions" -> "SDK Managers"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228338/477ec42b-e580-df88-593f-9d61d1e174dd.png)

使用するAndroid versionにチェックを入れ、
"Apply" -> "OK"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228338/1031796f-6f77-937b-f826-b8e270d988ed.png)

追加コンポーネントのインストールを待つ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228338/023571f1-a6a3-88f8-2eee-789814585440.png)

必要な方は下記も実施
> ヒント: アプリケーションのリストから Android Studio を利用できるようにするには、Android Studio のメニューバーから [Tools] > [Create Desktop Entry] を選択します。

## 環境変数とPath
下記は単体ユーザで環境変数を追加し、adb等のpathを通す例。.bashの末尾に追記。
```console
$ vim ~/.bashrc
export ANDROID_HOME="$HOME/Android/Sdk"
export JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"
export ADB="$ANDROID_HOME/platform-tools/adb"
export PATH=$PATH:$ANDROID_HOME/platform-tools
```
上記を保存したあと、環境変数を適用。
```console
$ source ~/.bashrc 
```

## Appium
```console
$ npm i -g appium
$ appium
[Appium] Welcome to Appium v2.4.1
[Appium] The autodetected Appium home path: /home/littlebit/.appium
[Appium] Appium REST http interface listener started on http://0.0.0.0:4723
[Appium] You can provide the following URLs in your client code to connect to this server:
[Appium] 	http://127.0.0.1:4723/ (only accessible from the same host)
[Appium] 	http://192.168.10.124:4723/
[Appium] No drivers have been installed in /home/littlebit/.appium. Use the "appium driver" command to install the one(s) you want to use.
[Appium] No plugins have been installed. Use the "appium plugin" command to install the one(s) you want to use.
```
 
## Appium UiAutomator2 Driver
AppiumがAndroidを操作するためのフレームワーク。
https://github.com/appium/appium-uiautomator2-driver
```console
$ appium driver install uiautomator2
✔ Checking if 'appium-uiautomator2-driver' is compatible
✔ Installing 'uiautomator2' using NPM install spec 'appium-uiautomator2-driver'
ℹ Driver uiautomator2@2.43.4 successfully installed
- automationName: UiAutomator2
- platformNames: ["Android"]
```

## Appium Inspector
AppiumをGUIで操作するツール。
https://github.com/appium/appium-inspector?tab=readme-ov-file#installing-on-linux
"Releases"から最新のビルド済みアプリ（.AppImageファイル）を適当なディレクトリにダウンロードし、実行権限を付与。
Appium-Inspector-linux-2023.12.2.AppImage
```console
$ pwd Appium-Inspector-linux-2023.12.2.AppImage
/home/littlebit/Android/AppiumInspector

$ chmod a+x Appium-Inspector-linux-2023.12.2.AppImage
```

実行
```console
$ ./Appium-Inspector-linux-2023.12.2.AppImage 
dlopen(): error loading libfuse.so.2

AppImages require FUSE to run. 
You might still be able to extract the contents of this AppImage 
if you run it with the --appimage-extract option. 
See https://github.com/AppImage/AppImageKit/wiki/FUSE 
for more information
```

ライブラリが無いとのエラーが出たので、インストール
```console
$ sudo apt install libfuse2 -y
```

再度実行
```console
$ ./Appium-Inspector-linux-2023.12.2.AppImage 
```

"JSON Representation"に必要最低限の設定
```json
{
  "platformName": "android",
  "appium:automationName": "UiAutomator2",
  "appium:deviceName": "xxxxxxxxxxxxx",
  "appium:udid": "xxxxxxxxxxxx"
}
```

"Start Session"をクリックし、Appium serverと接続に成功するとスマホ画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228338/d6bdfd84-9d80-e5a5-1505-714b310369d8.png)


"Session Information" tabを見ると、同様のセッションを開始するコード例が記載されている。
```python
# This sample code supports Appium Python client >=2.3.0
# pip install Appium-Python-Client
# Then you can paste this into a file and simply run with Python

from appium import webdriver
from appium.options.common.base import AppiumOptions
from appium.webdriver.common.appiumby import AppiumBy

# For W3C actions
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.actions import interaction
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.pointer_input import PointerInput

options = AppiumOptions()
options.load_capabilities({
	"platformName": "android",
	"appium:automationName": "UiAutomator2",
	"appium:deviceName": "xxxxxxxxxxxxx",
	"appium:udid": "xxxxxxxxxxxxx",
	"appium:ensureWebviewsHavePages": True,
	"appium:nativeWebScreenshot": True,
	"appium:newCommandTimeout": 3600,
	"appium:connectHardwareKeyboard": True
})

driver = webdriver.Remote("http://127.0.0.1:4723", options=options)


driver.quit()
```

以上、導入編でした。

# 参考
https://aurigait.com/blog/how-to-setup-appium-in-ubuntu/