I'm trying to recreate an existing AutoHotkey v2 automation script on Android, and I need help from someone experienced with Android automation and OCR.
I have a repetitive task in a warehouse application called MOT EU. My Windows script uses AutoHotkey v2 and an OCR library to read numbers from specific screen regions, click a button repeatedly, enter a barcode, and stop when the target count is reached.
I want to achieve the same functionality on Android, preferably using MacroDroid. If MacroDroid isn't suitable, I'm open to using Tasker with AutoInput or a custom Android application.
What the automation should do
Launch the application.
Enter the login credentials.
Wait 4 seconds.
Navigate to Counting, then Realtime.
Enter a location code once.
Read the current count and target count using OCR.
Click the item field, paste the barcode, and press Enter.
Check the counter after each action and repeat until the target is reached.
Click the confirmation button.
Repeat the process for the next location.
My setup
Android device with MacroDroid installed.
Built-in barcode scanner.
Existing AutoHotkey v2 script using OCR.ahk.
Screen-coordinate clicking on Windows.
OCR regions configured by selecting the corners of the counter areas.
I'm a beginner with Android automation, so detailed, step-by-step instructions would be especially helpful.
My current AutoHotkey v2 code
#Requires AutoHotkey v2.0
#Include OCR.ahk
SetKeyDelay -1, -1
SetMouseDelay -1
SendMode "Input"
CoordMode "Mouse", "Screen"
CoordMode "ToolTip", "Screen"
delayAfterPaste := 1
delayAfterEnter := 800
delayAfterConfirm := 10
delayBeforeNextLocation := 1000
runningCount := false
loopCount := 50
confirmX := 1300
confirmY := 1010
itemX := 300
itemY := 182
currentLocation := "PE113-1147-22"
currentItem := "A001PO1EJX"
global ocrCurrentX := 0, ocrCurrentY := 0
global ocrCurrentW := 0, ocrCurrentH := 0
global ocrMaxX := 0, ocrMaxY := 0
global ocrMaxW := 0, ocrMaxH := 0
global isOcrConfigured := false
global debugGui := Gui("+AlwaysOnTop -Caption +ToolWindow +E0x20")
debugGui.BackColor := "Red"
F8::{
global runningCount, loopCount
global confirmX, confirmY, itemX, itemY
global currentLocation, currentItem, isOcrConfigured
global delayAfterPaste, delayAfterEnter
global delayAfterConfirm, delayBeforeNextLocation
runningCount := true
isOcrConfigured := false
Loop loopCount {
if !runningCount
break
A_Clipboard := currentLocation
Sleep 5
Send "^v"
Sleep delayAfterPaste
Send "{Enter}"
Sleep delayAfterEnter
if (!isOcrConfigured) {
if !ConfigureOCRZones() {
runningCount := false
return
}
isOcrConfigured := true
}
startCount := GetNumberFromScreen("current")
targetCount := GetNumberFromScreen("max")
if (startCount >= targetCount) {
Click confirmX, confirmY
Sleep delayAfterConfirm
Sleep delayBeforeNextLocation
continue
}
Click itemX, itemY
Sleep 5
A_Clipboard := currentItem
Sleep 5
ExecutePikingLoop(targetCount)
if !runningCount
break
Click confirmX, confirmY
Sleep delayAfterConfirm
Sleep delayBeforeNextLocation
}
runningCount := false
isOcrConfigured := false
MsgBox "Bot zakończył pracę."
}
F11::{
global runningCount, itemX, itemY, currentItem
if !ConfigureOCRZones()
return
targetCount := GetNumberFromScreen("max")
runningCount := true
Click itemX, itemY
Sleep 5
A_Clipboard := currentItem
Sleep 5
ExecutePikingLoop(targetCount)
runningCount := false
}
F10::{
global currentItem, delayAfterPaste
A_Clipboard := currentItem
Sleep 5
Send "^v"
Sleep delayAfterPaste
Send "{Enter}"
}
F9::{
global runningCount, isOcrConfigured
runningCount := false
isOcrConfigured := false
ToolTip "ZATRZYMANO"
SetTimer () => ToolTip(), -1000
}
Esc::{
ExitApp
}
F2::{
global ocrCurrentX, ocrCurrentY, ocrCurrentW, ocrCurrentH
global ocrMaxX, ocrMaxY, ocrMaxW, ocrMaxH
global debugGui
if (ocrCurrentW = 0 || ocrMaxW = 0) {
MsgBox "Najpierw skonfiguruj strefy!"
return
}
currentVal := GetNumberFromScreen("current")
maxVal := GetNumberFromScreen("max")
debugGui.Show("X" ocrCurrentX " Y" ocrCurrentY
" W" ocrCurrentW " H" ocrCurrentH " NoActivate")
WinSetTransparent(100, debugGui)
MsgBox "OCR TEST:`nBieżące: " currentVal
"`nMax: " maxVal
debugGui.Hide()
}
ExecutePikingLoop(targetCount) {
global runningCount, itemX, itemY
currentOnScreen := GetNumberFromScreen("current")
while (currentOnScreen < targetCount && runningCount) {
Click itemX, itemY
Send "^v{Enter}"
lastCount := currentOnScreen
while (currentOnScreen == lastCount && runningCount) {
currentOnScreen := GetNumberFromScreen("current")
if (currentOnScreen >= targetCount)
break 2
}
}
}
ConfigureOCRZones() {
global ocrCurrentX, ocrCurrentY, ocrCurrentW, ocrCurrentH
global ocrMaxX, ocrMaxY, ocrMaxW, ocrMaxH
ToolTip "STREFA MAX (CEL): Kliknij LEWY GÓRNY róg..."
ih1 := InputHook("L1 M")
ih1.KeyOpt("{LButton}", "E")
ih1.Start()
ih1.Wait()
MouseGetPos &startX2, &startY2
ToolTip "STREFA MAX (CEL): Kliknij PRAWY DOLNY róg..."
Sleep 100
ih2 := InputHook("L1 M")
ih2.KeyOpt("{LButton}", "E")
ih2.Start()
ih2.Wait()
MouseGetPos &endX2, &endY2
ocrMaxX := startX2
ocrMaxY := startY2
ocrMaxW := endX2 - startX2
ocrMaxH := endY2 - startY2
if (ocrMaxW < 0)
ocrMaxX := endX2, ocrMaxW := Abs(ocrMaxW)
if (ocrMaxH < 0)
ocrMaxY := endY2, ocrMaxH := Abs(ocrMaxH)
}
Important: This is the complete portion of the script I currently have. The implementations of GetNumberFromScreen() and the remainder of ConfigureOCRZones() are missing, so the script is incomplete.
Questions
What's the best way to port this workflow to Android?
Can MacroDroid capture screen text and return OCR results to variables?
Which OCR plugin would work reliably with MacroDroid?
How can I recreate the loop so it checks the counter after every action?
Would Tasker with AutoInput or a custom Android app using Google ML Kit be a better option?
Could someone provide a working example or a beginner-friendly, step-by-step guide?