透過 uiautomator2 就能用 python 開發自動點擊下載 HamiBook 的書,徹底擺脫擾人的 Android Studio!
Hami 書城是中華電信的電子書服務 ,有提供月讀包可以付費每個月一百多台幣,在 Android 的 App 上就可以無限制下載所有到當期的雜誌報紙書籍。當然最多只能同時有幾台裝置登錄,下載的雜誌也只能在 HamiBook 的 App 上面打開觀看。
但其實是可以還原的回來的
在訂閱的期間,常常需要無時無刻地打開 App ,看看有沒有新的報紙雜誌,然後點擊下載的按鈕。每天都做一樣重複的事情令人心煩意亂,很久之前就在研究如何自動化這件事。
自動化是可以的,Android 上有一個測試用的工具,叫做 uiautomator,可以判斷畫面上有什麼元件,然後點擊或是做其他動作,整合起來就能達成自動下載的功能。
第一代的 hamiauto 就是用 uiautomator 寫的,基本上是用 java 開發一個 apk,安裝到手機上,然後定期用 adb
去執行這個 Activity。
儘管有點麻煩,但是是有效的。不過因為本質上就是開發一個 apk,所以整套的 Android Studio 需要安裝起來,還得隨時更新,儘管可以使用 command line 編譯部屬,但還是相對麻煩。
所以有 uiautomator2 的出現,在手機上安裝通用的 android-uiautomator-server 與提供 HTTP RPC 服務的 openatx,就能夠用 python 來寫原本的測試邏輯。
自動化的程式安裝起來當然也要自動化,只要先裝好 pip install -U uiautomator2
,上面的背景服務準備步驟,都會在第一次連接的時候會自動安裝好!超酷的 !
import uiautomator as u2
d = u2.connect()
print(d.info)
就只需要 python 環境安裝即可,不需要 Android Studio 了!多美好的世界啊 !
接著就可以用包裝好的 api 做原本 uiautomator 的事情,常用的像是等待某個按鈕出現然後點擊:
d(resourceId=f'{SHE_ID}/main_header_setting_btn').click()
或者是得到裡面的文字,讚的是可以用 python 的字串處理:
last_memory_gb = float(
d(resourceId=f'{SHE_ID}/tv_last_memory').get_text()
.split(':')[1].split()[0])
這麼串下去就是完整的自動化了。
uiautomator2 都建議直接用真的手機來連,但如果能夠直接用 android emulator 來用就更好了,不用另外準備一隻手機。
看了一下 uiautomator2 所提供編譯好的 openatx,支援 linux_386, linux_armv7 等等的包裝,看起來沒有問題。
不過當在 Apple M1 的電腦上用 Android Emulator Preview 版去跑卻發生不能執行的問題,原來是因為目前的預覽版還不能支援 32bit ARM,可能暫時還沒辦法在上面。
這樣就先選用 x86 的 system image 吧,透過 Android 的 Command Line Tools 就可以避免先下載 Android Studio 了。(網路上很多 Android Studio 的 meme 圖)
################################################################################
# avd
################################################################################
CMDLINE_TOOLS_URL := \
https://dl.google.com/android/repository/commandlinetools-linux-6858069_latest.zip
.PHONY: install/cmdline-tools
install/cmdline-tools:
@ mkdir -p install
@ cd install && \
wget $(CMDLINE_TOOLS_URL)
@ cd install && unzip commandlinetools-linux-6858069_latest.zip
.PHONY: install/sdk
install/sdk:
@ yes | install/cmdline-tools/bin/sdkmanager \
--sdk_root=$$PWD/install/sdk --licenses
@ install/cmdline-tools/bin/sdkmanager --sdk_root=$$PWD/install/sdk \
--install "cmdline-tools;latest"
.PHONY: avd/create
avd/create:
@ # sdkmanager --sdk_root=install/sdk --list
@ sdkmanager --sdk_root=$$PWD/install/sdk \
--install "system-images;android-28;google_apis;x86"
@ sdkmanager --sdk_root=$$PWD/install/sdk --install "platform-tools"
@ sdkmanager --sdk_root=$$PWD/install/sdk --install "platforms;android-30"
@ avdmanager --verbose create avd -k \
"system-images;android-28;google_apis;x86" \
-n hami -d "pixel_3a_xl"
@ echo "hw.keyboard=yes" \
>> $$HOME/.android/avd/hami.avd/config.ini
@ echo "disk.dataPartition.size=16384MB" \
>> $$HOME/.android/avd/hami.avd/config.ini
.PHONY: avd/run
avd/run:
@ @ $$(which emulator) -avd hami &
可以看到是自動在點的,滑鼠都沒有在動。
在經過好幾次修正確定之後,其實也可以讓 Android Emulator 不用顯示出來,在後面偷偷跑就好。
.PHONY: avd/run/nowin
avd/run/nowin:
@ @ $$(which emulator) -avd hami -no-window &
完成了自動化之後,接下來就可以配合其他的工具了,像是 rclone, rsync 等等,原本第一代的 hamiauto 拆了好幾個元件,現在透過 uiautomator2 全部都可以在一隻 hami.py 裡完成,開發疊代也比較快速,環境也比較獨立。
下次還有其他的需求,一樣繼續用的啦!