Delphi 製アプリを WSA (Windows Subsystem for Android) で動作させるための要点

# はじめに

Insider Preview 版でない Windows 11 でも **WSA (Windows Subsystem for Android)** が利用可能になりました。

 - [ついに日本でもAndroidアプリがWindows上で動作 ～「Amazon アプリストア」プレビュー版が一般提供 (窓の杜)](https://forest.watch.impress.co.jp/docs/news/1434767.html)
 - [Windows 11で動くAndroidアプリ ～ その背景にあるもの (ITmedia)](https://www.itmedia.co.jp/news/articles/2106/27/news023.html)

# WSA (Windows Subsystem for Android)

WSA (Windows Subsystem for Android) は Android アプリケーションを Windows 11 デバイスで実行できるようにするものです。

 - [Android™️ 用 Windows サブシステム (learn.microsoft.com)](https://learn.microsoft.com/ja-jp/windows/android/wsa/)

大雑把に言うと x86 向け Android が仮想環境で動作しています。基本的には x86 向けにビルドされたアプリケーションしか動作しないのですが、**Native Bridge** [^5] という仕組みにより ARM 向けバイナリも一応動作します。

**See also:**

 - [Android-x86 (android-x86.org)](https://www.android-x86.org/)
 - [BlueStacks (bluestacks.com)](https://www.bluestacks.com/ja/index.html)

## WSA のインストール
\[Microsoft Store\] から **『Amazon アプリストア』** を検索してインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/2c382b9c-f223-86df-ad1e-dc6b0814544f.png)
『Amazon アプリストア』をインストールするとスタートメニューに **『Android 用 Windows サブシステム設定』** が追加されます。

インストール後は念のために Windows を再起動してください。

**See also:**

 - [Amazonアプリストア (apps.microsoft.com)](https://apps.microsoft.com/store/detail/amazon%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B9%E3%83%88%E3%82%A2/9NJHK44TTKSX)

## Delphi IDE から WSA を認識させる方法 

1．まずは Delphi の IDE で Android ビルド向けの設定を終わらせておいてください。
 - [Android モバイル アプリケーション開発 (DocWiki)](https://docwiki.embarcadero.com/RADStudio/ja/Android_%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA)

2．スタートメニューから『Android 用 Windows サブシステム設定』を起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/13bfecbb-ff3b-8613-2dbd-35efe3c30e7b.png)
3．開発者モードを ON にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/3e0fd8c1-761b-be9f-40e7-acd47b75e86c.png)
4．\[開発者向け設定の管理\]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/9ed74c17-27e3-7f07-a98f-f1c2a66a07c0.png)
5．これで WSA が起動します [^3]。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b100820d-fa70-28b8-78ab-f6e413264368.png)
6．**ADB.EXE** のある場所 [^1] へ行き `adb connect 127.0.0.1:58526` [^4] を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/c7846bba-8174-864a-0242-e3bf010ced50.png)
7. 正しく接続されると、Android プラットフォームの [ターゲット] に **Subsystem for Android(TM)** が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/625e40c4-fae9-b87d-145e-4feb9677e1bf.png)

### unauthorized

adb connect で `127.0.0.1:58526 unauthorized` が出て、接続はされてるけど許可されていない状態になる場合は、一旦 `adb kill-server` で接続を切り、開発者向けオプションで、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b4f48f7c-e584-962f-2955-76fd52d78cad.png)

 1. USB デバッグ OFF
 2. USB デバッグの許可の取り消し
 3. USB デバッグ ON

と操作し、そして再度
 
```text
adb connect 127.0.0.1:58526
```

すると、ダイアログが出るので、ここで許可を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/ac522c8b-37e6-3d23-f42e-2948d488a215.png)

```text
C:\Users\Public\Documents\Embarcadero\Studio\22.0\CatalogRepository\AndroidSDK-2525-22.0.46141.0937\platform-tools> adb connect 127.0.0.1:58526
connected to 127.0.0.1:58526
```

このような表示になれば OK です。

## サイドローディング
サイドローディングとはストアアプリを経由しないアプリのインストール方法です。非公式ですが Microsoft 謹製のサイドローディングツールもあります。

 - [サイドローディング (Wikipedia: en)](https://en.wikipedia.org/wiki/Sideloading)
 - [WSATools (apps.microsoft.com)](https://apps.microsoft.com/store/detail/wsatools-apk-installer-and-more/9N4P75DXL6FG?hl=ja-jp&gl=jp)

### Delphi IDE によるサイドローディング
結論から言うと、そのままでは Delphi IDE を用いたサイドローディングはできません。デプロイ (配置) はできますが、正しく動作しません。

### Delphi で作ったアプリを WSA で動作させる

以下、Delphi で作ったアプリをサイドローディングして WSA で動作させる方法です。

#### サイドローディング用スクリプトの登録
まずはサイドローディング用のスクリプトを Delphi IDE に登録します。
 1. [スクリプト (manualadb.bat)](https://gist.github.com/jimmckeeth/3a453ccdb1a387644ca137b499d01879) を適当な場所に保存します。
 2. `[ツール | ツールの構成]` を選び、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/6af3bd1c-84d1-5a5d-651a-edb23475cb70.png)
 3. [追加] ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b9c689f1-1a32-afa2-b221-06fb4c6d9cb1.png)
 4. 次のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/7ee0f7b5-ad15-4ccc-dc45-e9303030840b.png)

| 項目 | 値 |
|:---|:---|
| タイトル | Manual ADB |
| プログラム | C:\Tools\manualadb.bat [^2] |
| 作業ディレクトリ | C:\Tools [^2] |
| パラメータ | \\$PATH(\\$EXENAME) \\$NAMEONLY(\\$PROJECT) |

このスクリプトを使うためには `ADB.EXE` のある場所にパスを通しておく必要があります。システム/ユーザー環境変数 `PATH` にパスを追加したくない場合にはスクリプトでパスを追加してください。以下に改変したスクリプトを示します。

```bat:manualadb.bat
@echo off
REM Call from Delphi/RAD Studio IDE with the following parameters
REM $PATH($EXENAME) $NAMEONLY($PROJECT)
set PATH=%PATH%;C:\Users\Public\Documents\Embarcadero\Studio\22.0\CatalogRepository\AndroidSDK-2525-22.0.46141.0937\platform-tools
set PACKAGE=com.embarcadero
echo =============================================================
echo Be sure you Compile Android 64 and Deploy [Shift-Ctrl-Alt-F9]
echo. 
echo Also set ^<application android:resizeableActivity=^"true^"^> in AndroidManifest.template.xml
echo =============================================================
echo Path: %1
set apk=%2\bin\%2.apk
echo APK: %apk%
cd %1
cd %2\bin
echo.
dir %2.apk
echo.
if exist %2.apk (
adb install -r --no-streaming %2.apk
adb shell am start -n %PACKAGE%.%2/com.embarcadero.firemonkey.FMXNativeActivity
echo You can close this window....
timeout /t 10
) else (
echo =============================================================
echo Your APK file is missing!
echo Be sure you Compile Android 64 and Deploy [Shift-Ctrl-Alt-F9]
echo =============================================================
pause
)
```

:::note info
上記スクリプトのパスは Delphi 11.2 Alexandria 用です。お手持ちの Delphi の環境に合わせて書き換えてください。

```bat:manualadb.bat
set PATH=%PATH%;<あなたの環境で ADB.EXE の格納されているパス>
```
:::

:::note info
プロジェクトオプションで `package` を変更した場合にも、スクリプトを書き換える必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/4f019494-bbad-fd3b-4a5d-9f4cdf356f44.png)

```bat:manualadb.bat
set PACKAGE=com.hogehoge
```
:::

**See also:**

 - [manualadb.bat (Github Gist: @jimmckeeth)]((https://gist.github.com/jimmckeeth/3a453ccdb1a387644ca137b499d01879))


#### Delphi アプリケーションの作成とデプロイ

最低限の手順を示すため、新規プロジェクトで説明します。

 1. Delphi のプロジェクトを作成 (`[ファイル | 新規作成 | マルチデバイスアプリケーション]`) し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/ac22ea14-b10e-2995-fc2c-c6e9cc23e5db.png)
 2. [プロジェクトマネージャ] でターゲットプラットフォームを `Android 64 ビット` に変更します。[ターゲット] に **Subsystem for Android(TM)** がある事を確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/ffaa9ad9-f424-716a-0e68-33555f364ffb.png)
 3. `[ファイル | プロジェクトに名前を付けて保存]` でプロジェクトを一旦保存します。
 4. 〔Shift〕+〔F9〕(`[プロジェクト | Project1 をビルド]`) でプロジェクトを一旦ビルドします。
 5. `[ファイル | 開く]` で `AndroidManifest.template.xml` を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/c6d65f65-13dd-e35a-7924-87270dbe007a.png)
 6. `android:resizeableActivity` の値を `true` に変更して保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/3124d420-a277-0541-a44e-3dacd86cf910.png)
 7. 適当なコントロールを貼ったりコードを書いてみてください。終わったら〔Shift〕+〔F9〕(`[プロジェクト | Project1 をビルド]`) でプロジェクトをビルドします。
 8. 〔Shift〕+〔Ctrl〕+〔Alt〕+〔F9〕(`[プロジェクト | libProject1.so の配置]`) で配置します。正しくビルド＆配置されていれば、プロジェクトフォルダの `Android64\Debug\Project1\bin` に APK ができているはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/5fe4c98e-f8de-e659-a42a-93302b7b6a7b.png)
 9. `[ツール | Manual ADB]` でサイドローディングを行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/739e616a-4764-4438-ae20-49c41d7b19c9.png)
サイドローディングされたアプリケーションは正しく動作しましたか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/60be73c3-dacf-979d-b71a-fbd108f814b5.png)

### サイドローディングしたアプリケーションのアンインストール

最初、サイドローディングしたアプリケーションのアンストール方法がわからずに焦りました。

#### その１
Windows 11 のスタートメニューからインストールされたアプリケーションのアイコンを右クリックして [アンインストール] を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/c4bad701-b3b2-c904-ebb3-899bb5727512.png)

#### その２
 1. 『Android 用 Windows サブシステム設定』を起動し、[開発者向けオプション] を表示。
 2. 右上の虫眼鏡アイコンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/76ceba4b-4267-f20f-0762-0c083deb7252.png)
 3. `アプリ` と入力。`アプリ (アプリ)` を探してクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/5eadba7a-6c25-5fc9-04d1-11ebc9ba27f4.png)
 4. アンインストールしたいアプリをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/fb0782c5-7165-350b-1354-1d7f6c4e12ea.png)
 5. [アンインストール] をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/ac087175-76e0-e253-644d-5b4323db4088.png)
 6. [OK] をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/883ab7c7-e254-c77d-31cb-bd8322a04814.png)

#### その２.５
`[設定]` 画面へ行くには ADB.EXE (Activity Manager) を使うのが簡単なようです。

```bat
adb shell am start -a android.intent.action.MAIN -n com.android.settings/.Settings
```

[設定] から [アプリ] へはすぐ行けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b8cef9dc-48af-e12d-ad0d-09bcea9a1d2a.png)

#### その３
ADB.EXE (Package Manager) を使ったアンインストールも可能です。

```bat
 adb shell pm uninstall -kパッケージ名
```

指定するパッケージ名は `com.embarcadero.Project1` みたいな感じです。


# おわりに
Delphi 製アプリを WSA (Windows Subsystem for Android) で動作させるための要点をまとめると、

- 事前に WSA を起動しておく [^3]。
- `adb connect 127.0.0.1:58526` [^4] で WSA へ接続する。
- ターゲットプラットフォームを **Android 64 ビット** にする。
- `AndroidManifest.template.xml` の `application android:resizeableActivity` の値を **true** に書き換える。
- スクリプトを使ってサイドローディングする。

となります。

:::note info
本記事はエンバカさんの記事の焼き直しです。日本語版の記事が無かったようなので書いてみました。細かい注意点などについては元記事及びスライドを参照してください。
:::

 - [Android on Windows 11: A Developer’s Perspective (blogs.embarcadero.com)](https://blogs.embarcadero.com/android-on-windows-11-a-developers-perspective/)
 - [Slides: Android on Windows 11 – A Developer’s Perspective (blogs.embarcadero.com)](https://blogs.embarcadero.com/wp-content/uploads/2022/03/Android-on-Windows-11-A-Developers-Perspective-Windows-Subsystem-For-Android-with-Jim-and-Scott-9396411.pdf)
 - [[RSP-32093] Android 11 Emulator Support (Quality Portal)](https://quality.embarcadero.com/browse/RSP-32093)

[^1]: Delphi 11.x の場合、デフォルトで `C:\Users\Public\Documents\Embarcadero\Studio\22.0\CatalogRepository\AndroidSDK-2525-22.0.46141.0937\platform-tools` です (または `C:\Users\Public\Documents\Embarcadero\Studio\22.0\CatalogRepository\AndroidSDK-2525-22.0.47991.2819\platform-tools`)。
[^2]: `manualadb.bat` を `C:\Tools` に保存した場合。
[^3]: 『Amazon アプリストア』や、そこからインストールしたアプリを実行する事でも WSA が起動します。
[^4]: WSA では `172.～` で始まる IP アドレスも割り当てられていますが、`127.0.0.1` での接続の方が簡単です。
[^5]: Native Bridge として Intel の **Houdini** (libhoudini.so) が使われているようです。