먹고공부하자 · 폰 자동화 노하우
안드로이드 앱, API 없이 코드로 조작하는 법
낡은 갤럭시 S8 한 대를 Mac에 물려서, 화면을 읽고 좌표를 누르는 방식으로 안드로이드 앱을 조작하는 방법을 정리합니다. 앱마다 따로 뚫을 필요가 없는, 한 번 익히면 계속 우려먹는 노하우입니다. 설명은 실제로 만들어본 매머드커피 자동 주문 봇을 예시로 이어갑니다.
안드로이드 앱을 코드로 조작한다고 하면 보통 “그 앱 API를 따야 하나?”를 먼저 떠올립니다. 여기서 쓰는 방법은 다릅니다. API도, 앱 내부 구조도 몰라도 됩니다. 필요한 건 딱 세 가지뿐입니다 — 화면을 사진처럼 찍고(캡처), 그 안의 글자를 읽고(OCR), 원하는 자리를 눌러주는(좌표 탭) 것. 이 세 가지는 어떤 앱을 켜놓든 똑같이 통합니다.
그러려면 먼저 컴퓨터가 폰 화면에 접근할 수 있는 통로부터 열어야 합니다. 안드로이드는 기본적으로 컴퓨터가 화면을 만지지 못하게 막아놓기 때문입니다. 그 잠금을 푸는 스위치가 개발자 모드고, 그 안에 또 하나 숨어 있는 스위치가 USB 디버깅입니다. 이 둘을 다 켜야 컴퓨터에서 adb라는 도구로 폰에 말을 걸 수 있습니다. 이 통로는 딱 한 번만 뚫으면 되고, 그 다음부터는 어떤 앱을 조작하든 다시 할 필요가 없습니다.
01 · Mac 쪽 준비
먼저 컴퓨터에 폰과 대화할 도구가 있는지 확인합니다. 없으면 한 줄로 설치됩니다.
02 · 폰에서 스위치 두 개 켜기
여기가 이번 셋업에서 실제로 가장 오래 걸린 구간입니다. 이유는 아래 인용에.
-
① 숨은 메뉴 열기
설정 안에 빌드번호를 일곱 번 연속으로 누르면 개발자용 메뉴가 나타납니다.
설정 → 휴대전화 정보 → 소프트웨어 정보 → 빌드번호 7번 연타“개발자 모드를 켰습니다” 메시지가 뜨면 성공입니다.
-
② USB 디버깅은 따로 켜야 한다
방금 연 개발자 옵션 메뉴 안, USB 디버깅이라는 별도 토글을 찾아 켭니다.
설정 → 개발자 옵션 → USB 디버깅 토글 ON확인 팝업이 뜨면 확인을 누릅니다.
-
③ 케이블 연결 후 용도를 “파일 전송”으로
Mac에 USB로 연결한 뒤, 폰 알림창에서 USB 연결 용도를 바꿔줍니다.
폰 상단바 알림 → USB 사용 용도 → 파일 전송(MTP)“충전 전용”이나 “테더링”으로 남아 있으면 컴퓨터가 폰을 아예 못 봅니다.
-
④ 이 컴퓨터를 신뢰하기
디버깅 연결이 처음 잡히는 순간, 폰 화면에 인증 팝업이 뜹니다.
“USB 디버깅을 허용하시겠습니까?” → 「항상 허용」 체크 후 확인
“개발자 모드를 켰다”와 “USB 디버깅을 켰다”는 완전히 다른 얘기다. 하나는 메뉴를 여는 열쇠고, 하나는 그 안에서 또 눌러야 하는 진짜 스위치.
03 · 잘 연결됐는지 확인
터미널에서 폰 목록을 불러봤을 때, 기기 이름과 함께 device라고 뜨면 끝입니다.
unauthorized라고 뜨면 위 ④번 인증 팝업을 놓친 것이니 폰 화면을 다시 확인하세요. 목록이 텅 비어 있으면 케이블이나 USB 모드(③번) 문제입니다.04 · 핵심 노하우: 화면을 읽고 누르는 4단계
연결이 뚫렸다면, 여기서부터는 앱과 무관한 하나의 반복 루틴입니다. 이 네 단계를 앱마다 계속 돌립니다.
-
① 화면을 사진으로 뜬다
지금 폰 화면을 통째로 캡처합니다. 이 시점의 폰 화면은 그냥 하나의 이미지 파일일 뿐이고, 어떤 앱인지는 중요하지 않습니다.
$ adb exec-out screencap -p > screen.png -
② 그 사진에서 글자를 읽는다 (OCR)
캡처한 이미지를 OCR에 넣으면 화면에 있는 모든 글자와, 그 글자가 화면의 어느 좌표에 있는지를 함께 돌려줍니다. 원하는 문구(예: “담기”, “결제하기”, “예매하기”)를 텍스트로 찾으면, 그 버튼의 위치도 같이 확보됩니다.
☕ 매머드 예시 — 화면을 읽었을 때 “아이스 아메리카노” 옆에 “담기”라는 글자가 (x:612, y:1450) 부근에서 잡혔다면, 그 좌표가 곧 눌러야 할 자리입니다. 메뉴가 개편돼서 버튼 위치가 바뀌어도 좌표를 미리 하드코딩할 필요 없이, 매번 새로 찾으니 그대로 대응됩니다. -
③ 그 좌표를 누른다
사람이 손가락으로 누르듯, adb가 그 좌표를 탭합니다.
$ adb shell input tap 612 1450 -
④ 화면이 바뀔 때까지 기다렸다가, ①로 돌아간다
버튼을 누르면 다음 화면(장바구니, 결제 확인 등)으로 넘어갑니다. 그 새 화면을 다시 캡처해서 다음 문구를 찾는 식으로, 목표(예: “결제 직전까지 담아두기”)에 닿을 때까지 ①~③을 반복합니다.
05 · 그래서, 다른 앱에 그대로 옮기려면
앞선 01~03(연결 뚫기)은 폰 한 대당 딱 한 번, 04(읽고-누르기)는 앱이 바뀌어도 그대로입니다.
-
연결은 앱을 모른다
adb는 “이 폰의 화면을 나에게 보여줘”, “이 좌표를 눌러줘”만 할 줄 압니다. 지금 화면에 매머드가 떠 있든, 은행 앱이든, 예매 사이트든 상관하지 않습니다.
-
바뀌는 건 “어떤 문구를 찾을지”뿐
새 앱으로 옮기고 싶으면 04단계에서 찾을 문구와, 목표에 닿기까지의 화면 순서만 그 앱에 맞게 바꾸면 됩니다. 01~03의 연결 셋업은 다시 안 해도 됩니다.
-
제약은 그대로 남는다
화면이 꺼지면 못 읽고, 잠금이 걸려 있으면 못 누르고, 결제·본인인증처럼 사람 확인이 필요한 지점은 여전히 사람 몫입니다 — 앱이 바뀌어도 이 규칙은 똑같습니다.
06 · 막혔던 순간들, 원인과 답
실제로 겪은 문제만 골라 묻고 답하는 방식으로 정리했습니다.
Q adb devices를 쳤는데 목록이 완전히 비어요.
A USB가 테더링이나 충전 전용 모드로 잡혀 있을 확률이 높습니다. 알림에서 파일 전송(MTP)으로 바꿔보세요. 그래도 안 되면 케이블 자체가 충전 전용 케이블일 수 있습니다 — 데이터 선로가 없는 저가 케이블이 꽤 흔합니다.
Q “스마트 스위치를 설치하라”는 팝업이 자꾸 떠요.
A macOS가 파일 탐색기로 폰을 열어보려는 안내일 뿐, adb 연결과는 무관한 통로입니다. 그냥 닫아도 됩니다.
Q 폰은 시스템에 보이는데 adb만 못 찾아요.
A 파일 전송용 인터페이스만 열려 있고 디버깅용 인터페이스는 없는 상태입니다. 02번 ②단계, USB 디버깅 토글을 다시 확인하세요.
Q 잠시 두면 화면이 꺼져서 자동화가 검은 화면만 찍어요.
A 절전모드입니다. adb shell svc power stayon true 한 줄이면 USB가 연결돼 있는 동안은 화면이 계속 켜져 있습니다.
Q 패턴 잠금화면에서 자동화가 그냥 멈춰요.
A 보안 잠금은 스크립트가 대신 풀어주지 않습니다. 실행 전에 사람이 손으로 한 번 잠금을 풀어두는 것까지가 준비 과정입니다. 이후엔 위 stayon 설정이 화면을 지켜줍니다.
07 · 새 앱에 적용할 때 체크리스트
틀은 앱과 무관하게 똑같습니다. 괄호 안은 매머드 예시로 든 값이니, 대상 앱에 맞게 바꿔서 쓰면 됩니다.
- 폰이 케이블로 연결돼 있고, adb devices에 device로 뜬다
- 폰 잠금이 미리 풀려 있다
- 대상 앱이 원하는 화면에 맞춰져 있다 (매머드: 로그인 상태 + 지점 연대동문점)
- 지금이 그 앱의 동작 가능 시간이다 (매머드: “모바일오더 준비중”이면 담기 자체가 막혀서 자동으로 중단된다)
python3 order.py --dry-run으로 매장·시간 상태만 먼저 점검하고, 문제없으면 python3 order.py로 담기를 실행합니다. 어떤 앱이든 결제·본인인증처럼 되돌릴 수 없는 마지막 버튼은 언제나 사람이 직접 누르는 걸 원칙으로 둡니다.
댓글 남기기