Skip to content

Repository files navigation

스마트 안드로이드

알림 정리와 기기 상태에 반응하는 개인용 자동화 앱.

MacroDroid로 하던 일 중 알림 삭제 · 블루투스/와이파이 반응 · 다른 앱에 신호 보내기만 남기고 직접 만든 것이다. 화면을 대신 눌러주는 기능은 넣지 않았다.

할 수 있는 일

언제 (트리거)

트리거 조건
알림 앱과 포함 문구
블루투스 기기별 연결/해제
와이파이 연결/해제

무엇을 (액션)

액션 설명
대기 다음 액션까지 기다린다
알림 삭제 앱과 문구로 골라 지운다
브로드캐스트 다른 앱에 신호를 보낸다 (예: AdGuard·WireGuard 켜기/끄기)
조건부 중단 블루투스 상태가 맞지 않으면 거기서 멈춘다

매크로를 길게 눌러 지금 실행을 고를 수 있다. 대기와 조건을 건너뛰고 바로 돌려 결과를 확인한다. 손이 필요한 매크로는 카드에 버튼이 따로 나온다.

목록 정리

매크로를 길게 누르면 복제하기폴더에 넣기가 나온다.

복제본은 이름 뒤에 복사본이 붙고 꺼진 채로 만들어진다. 같은 트리거가 둘이 한꺼번에 도는 것을 막으려는 것이다. 고쳐서 켜면 된다.

폴더는 따로 만들지 않는다. 이름을 적으면 그때 생기고, 마지막 매크로가 빠지면 사라진다. 폴더는 처음에 다 접혀 있다. 펼친 것만 기억해서, 앱을 껐다 켜도 그대로다.

폴더를 고르는 자리에서 함께 옮길 매크로를 같이 고를 수 있다. 하나씩 세 번 옮기지 않아도 된다. 넣은 폴더는 바로 펼쳐진다. 접힌 채로 두면 방금 옮긴 것이 사라진 것처럼 보이기 때문이다.

목록은 키로 말한다

열세 개가 다 잘 돌고 있으면 목록은 한 화면이다. 조용한 매크로는 이름과 마지막 시각만 있는 한 줄이고, 손이 필요한 것 — 지금 돌고 있거나, 알람에 맡긴 대기가 남았거나, 지난번에 실패한 것 — 만 레일과 까지 펼친다.

충전 완료 알림 지우기          어제 17:58  실행
홈 도착 VPN 켜기                   15:28  실행
┌──────────────────────────────────────────┐
│ 회사 와이파이 광고차단          ▶   ●━━  │
│   ● 와이파이 연결                        │
│   · 30분 대기                            │
│   ■ 브로드캐스트 …AUTOMATION · start     │
│   17:23  이어서 함                    ×  │
└──────────────────────────────────────────┘
야간 방해금지 알림 정리            아직 안 돎

한때 열세 장이 모두 이 큰 모양이어서 목록이 네 화면이었다. 그런데 매크로를 훑는 사람이 찾는 것은 「무엇을 하는지」가 아니라 「멈춘 게 있나」다. 구성은 한 탭 뒤로 보냈다. 흘려 봐도 키가 큰 것이 봐야 할 것이다.

이름은 접힌 줄과 펼친 카드가 같은 x에서 시작한다. 눈이 한 열만 따라 내려가면 된다.

매크로가 마지막으로 무엇을 했는지

접힌 줄은 이름 오른쪽, 펼친 카드는 맨 아래 한 줄이 그것만 말한다.

23:19  이어서 함          ← 알람에 맡겨 둔 대기가 남아 있다 (앰버 = 시간)
22:49  실패              ← 지난번에 브로드캐스트가 막혔다 (빨강)
어제 21:35  실행         ← 마지막으로 끝까지 돌았다
아직 안 돎               ← 만든 뒤 한 번도 걸리지 않았다

이 앱의 유일한 약속은 「네가 안 보는 동안 일어났다」다. 그런데 목록이 구성만 보여 주면 무장된 것과 한 번도 안 돈 것을 구별할 수 없다. 30분 매크로가 조용히 안 돌았을 때 앱만 보고 진단할 수 없던 이유가 그것이었다.

시각만 고정폭이다. 이 앱은 기계값에만 고정폭을 쓴다. 펼친 카드에서 그 줄을 누르면 실행 기록으로 간다.

엔진이 도는지 보기

목록 위 한 줄이 그것만 말한다. 점이 숨쉬면 살아 있는 것이다. 누르면 실행 기록으로 간다.

● 켜져 있음 · 매크로 13개 · 마지막 23:19

한때 이 자리를 비우고 상태를 메뉴 안에 넣었다. 잘 돌 때 자리를 아끼자는 판단이었는데, 실제 실패는 「다 정상으로 보이는데 안 돈」 경우였고 그때 사람은 메뉴를 열 이유를 모른다. 그래서 돌려놓되 놀라게 하지 않을 만큼만 조용히 뒀다.

알림 접근 권한이 꺼져 있으면 이 앱은 아무것도 하지 않는다. 그때는 그 자리에 빨간 띠가 대신 선다. 블루투스 매크로를 켜 뒀는데 근처 기기 권한이 없을 때도 같은 자리에 뜬다. 그 권한 없이는 연결·해제를 알 수 없다.

기록은 파일에도 남는다. 안드로이드가 앱을 정리하면 메모리에 있던 기록이 통째로 사라져서, 정작 무엇이 잘못됐는지 알아야 할 때 아무것도 없었다.

실행 기록은 하루씩 묶인다

날짜는 줄마다 되풀이하지 않고 묶음의 머리글로 올린다. 그래서 시각은 늘 여덟 글자고, 오른쪽 글이 모든 줄에서 같은 x에서 시작한다. 전에는 오늘 줄과 지난 줄이 여섯 칸 어긋나 있었다.

오늘
12:20:08   ▶ 회사 와이파이 광고차단 · 30분 뒤에 이어감
12:00:02   브로드캐스트를 보내지 못함 · 권한 없어 거부됨      ← 빨강
11:20:45   WireGuard 터널 켜기 · home-server
08:02:09   엔진 시작 · 매크로 13개                          ← 연한 회색

어제
22:10:01   ▶ 충전 완료 알림 지우기

엔진 상태 줄은 하루에 한 번씩만 남는다. 엔진이 재바인딩될 때마다 「엔진 시작 …」과 「블루투스 · 지금 붙어 있는 …」이 함께 찍혀서, 32초에 네 번이면 여덟 줄이 정작 찾으려던 두 줄을 덮었다. 줄이는 것은 이 상태 줄뿐이다 — 실행·삭제·전송 같은 결과 줄은 되풀이돼도 사실이고, 기록을 여는 이유가 대개 그 줄이다.

걸러 보는 칩(전부 / 실패·멈춤만)과 엿보기 스위치는 위에 고정된다. 걸러 놓고 스크롤하면 칩이 위로 밀려 올라가 「전부」로 돌아올 길이 화면에서 사라졌다.

스위치를 끄면 예약도 거둔다

「30분 뒤에」가 예약된 상태에서 매크로를 끄면 그 예약도 함께 지워진다. 전에는 예약이 살아남아 꺼 둔 매크로가 30분 뒤에 브로드캐스트를 쏘았다. 카드가 「23:19 이어서 함」과 꺼진 스위치를 동시에 보여주던 시절의 일이다.

예약을 남긴 채 이번 한 번만 취소하고 싶으면 상태줄 오른쪽 ×를 누른다.

실패는 알림으로 온다

켜 둔 매크로가 돌지 못하면 조용한 알림 하나가 온다 — 매크로 이름과 무엇이 막혔는지. 소리도 진동도 없다. 실패를 알리는 일이 그 자체로 성가신 알림이 되면 이 앱이 하려던 일과 반대가 된다.

앱을 열 이유는 이미 뭔가 이상하다고 느낀 뒤에야 생긴다. 그전에 알려주는 채널이 없으면 터널이 안 붙은 것을 다른 앱에서 먼저 알게 된다.

오래 기다리는 매크로

「30분 뒤에」처럼 2분을 넘는 대기는 알람에 맡긴다. 남은 단계가 몇 번째인지 적어 두고 시스템에 깨워 달라고 부탁한다. 그래서 기다리는 동안 안드로이드가 앱을 정리해도 시각이 되면 이어서 한다. 기록에 이렇게 남는다.

21:35:12  30분 뒤에 이어서 함 · WireGuard 켜기 (차 내리고 30분 뒤)
22:06:48  ▶ WireGuard 켜기 (차 내리고 30분 뒤) · 대기 뒤 이어서

허락이 필요 없는 느슨한 알람을 쓰기 때문에 몇 분 늦을 수 있다. 30분이 32분이 되는 정도다.

블루투스는 두 겹으로 본다

연결·해제 알림만 믿으면 놓치는 자리가 있다. 앱이 정리된 사이에 일어난 일은 오지 않고, 알림이 오더라도 그때 앱이 살아 있어야 받는다. 차에서 내린 그 한 번을 놓치면 30분 뒤에 할 일도 함께 사라진다.

그래서 10분마다 지금 붙어 있는 기기를 시스템에 직접 물어본다. 기억하던 것과 다르면 그때 매크로를 돌린다. 오디오와 통화 프로필을 함께 보므로 차량처럼 오디오로 붙는 기기도 잡힌다.

WireGuard 터널 켜고 끄기

브로드캐스트로 터널을 여닫을 수 있다. WireGuard 설정에서 원격 제어 앱 허용을 먼저 켜야 한다.

켜기 끄기
액션 com.wireguard.android.action.SET_TUNNEL_UP com.wireguard.android.action.SET_TUNNEL_DOWN
받을 앱 패키지명 com.wireguard.android 같음
리시버 클래스 com.wireguard.android.model.TunnelManager$IntentReceiver 같음
추가값 이름 tunnel 같음
추가값 터널 이름 같음

WireGuard가 리시버에 자기 권한을 걸어 두어서, 없으면 신호가 아무 말 없이 버려진다. 그런 매크로가 생기면 앱이 그때 권한을 묻는다.

내가 정한 값은 진하게 남는다

요약 문장에서 사람이 고른 값만 진한 잉크에 굵게 나온다. 앱이 붙인 문법은 연하다.

Tesla Model Y Why 블루투스 해제        ← 기기 이름이 값
30분 대기                              ← 시간이 값
WireGuard 터널 켜기 · home-server      ← 프리셋 이름은 앱 말, 터널 이름이 값
토스 · "결제" · 5초 뒤 지움
와이파이 연결                          ← 고른 값이 없으면 전부 연하다

문장 편집기는 채워진 칸에 색을 깔아 같은 말을 한다. 한 줄 요약에는 칸을 깔 자리가 없으니 글자 무게로 옮겼다. 색은 쓰지 않았다 — 이 앱의 청록은 이미 「선택됨」과 「누를 수 있는 것」 두 뜻을 나눠 쓰고 있어서, 세 번째 뜻을 얹으면 색이 아무 말도 하지 않게 된다.

값과 문법을 가르는 기준은 한 곳(Part)에 있고 요약 문자열도 거기서 나온다. 둘이 어긋날 수 없다.

편집 화면은 접혀 있다

「직접 짜기」로 들어가면 트리거와 단계가 모두 접힌 한 줄로 있다. 손댈 것만 눌러 펼친다. 한 번에 하나만 열린다 — 다른 것을 열면 앞의 것은 접힌다.

● 1  Tesla Model Y Why 블루투스 해제      ›
또는
● 2  와이파이 연결                        ›

· 1  30분 대기                            ›
○ 2  Tesla Model Y Why 연결됐으면 중단    ›
■ 3  WireGuard 터널 켜기 · home-server    ⌄   ← 펼침
■ 4  헤이홈 알림 삭제                     ›

접힌 줄에는 목록 카드가 쓰는 그 요약을 그대로 쓴다. 새 언어를 만들지 않았다. 그래서 다 접힌 편집 화면은 목록 카드와 똑같이 읽힌다.

옮기고 빼는 버튼은 펼친 것에만 있다. 접힌 줄에 조작점이 넷이면 다시 복잡해진다.

「언제」와 「무엇을」은 같은 모양이다 — 머리글 + 조각 카드 여러 장 + 추가 버튼. 전에는 트리거만 공용 카드 하나 안에 들어 있어서, 같은 조각인데 한쪽은 카드 속 줄이고 한쪽은 제 카드였다.

브로드캐스트는 아는 것부터 고른다

이 앱이 하는 일의 절반이 브로드캐스트인데, 한 글자만 달라도 신호는 조용히 버려진다. 그래서 자주 쓰는 것은 앱이 채운다.

WireGuard 터널 켜기   WireGuard 터널 끄기
AdGuard 보호 켜기     AdGuard 보호 끄기

패키지·리시버·액션·추가값 이름 네 칸이 한 번에 채워지고, 사람은 자기만 아는 값 하나만 적는다. 켜기↔끄기를 바꿔도 이미 적어 둔 터널 이름은 남는다.

비밀번호는 가린다. 추가값 이름이 password·token·key 같은 것이면 화면에 •••••로 나오고, 목록 요약에도 값을 내보내지 않는다. 눈 버튼으로 확인할 수는 있다.

막힐 이유는 저장 전에 말한다. 리시버가 없거나 권한이 없으면 그 자리에서 붉은 줄로 알려 준다. 엔진이 실행할 때 쓰는 것과 같은 판정이라, 「괜찮다」고 말한 뒤 조용히 버려지는 일이 없다.

고르는 자리는 시트로 올라온다

앱·기기·떠 있는 알림·단계 넷은 화면 아래에서 올라오는 시트로 고른다. 작은 창에 수백 줄을 밀어 넣지 않고, 확인 버튼 자리가 값을 적용하는 버튼이 되지도 않는다. 「모든 앱으로」처럼 값을 비우는 일은 목록 밖 제자리에 있다.

앱 고르기는 런처에 아이콘이 있는 앱부터 세운다. 전에는 첫 화면이 「2 Button Navigation Bar」 같은 시스템 조각부터 시작했다. 그런 것도 숨기지 않고 「그 밖에」 아래로 보낸다 — 런처 아이콘 없는 앱의 알림을 지워야 할 때가 있다.

MacroDroid 파일 주고받기

메뉴에서 .mdr 백업을 가져오고 내보낼 수 있다. 서로 다루는 범위가 달라서 옮기지 못한 항목은 가져온 뒤 이름까지 알려준다. 조건 분기(If/Else)는 옮기지 않는다.

접근성 서비스를 쓰지 않는다

이 앱에는 AccessibilityService가 없다. 화면을 읽거나 누르는 기능이 코드에 존재하지 않는다. 쓰는 권한은 아래가 전부다.

  • 알림 접근 — 알림을 읽고 지운다
  • 블루투스 연결 — 기기 연결/해제를 안다
  • 네트워크 상태 — 와이파이 연결/해제를 안다
  • 앱 목록 조회 — 매크로를 만들 때 앱을 고른다
  • 인터넷 · 패키지 설치 — 새 버전을 받아 스스로 갱신한다

화면 밝기

메뉴 → 화면을 누르면 기기 설정 따름 → 밝게 → 어둡게 순으로 돌아간다. 메뉴는 닫히지 않으므로 색이 바뀌는 것을 보고 고르면 된다. 한 번 정하면 기기가 밤이 되어도 그 값을 지킨다.

업데이트

메뉴 → 업데이트에서 확인한다. 켜 두면 하루 한 번 스스로 확인해 새 버전을 받아 깐다. 안드로이드가 앱의 자가 설치를 제한하기 때문에 처음 한 번은 설치 확인 화면이 뜬다. 그 뒤로는 확인 없이 갱신된다.

APK는 전용 릴리스 키로 서명한다. 서명이 다르면 설치가 거부되므로 같은 키로 서명한 APK끼리만 갱신된다. 키는 ~/.android/smart_android.jks에 있고 비밀번호는 local.properties에 적혀 있다. 둘 중 하나라도 잃으면 이후 갱신을 배포할 수 없다. 따로 백업해 둘 것.

빌드

./gradlew :app:assembleRelease        # 배포용. app/build/outputs/apk/release/
./gradlew :app:assembleDebug          # 개발용. 디버그 키로 서명된다
./gradlew :app:testDebugUnitTest      # 단위 테스트

배포하는 APK는 항상 assembleRelease로 뽑는다. 디버그 키로 서명된 APK는 Play Protect가 더 자주 막고, 릴리스 키로 서명한 것과 서로 갱신되지 않는다.

local.properties에 SDK 경로와 서명 정보가 필요하다. 이 파일은 저장소에 올리지 않는다.

sdk.dir=/path/to/Android/Sdk
releaseStoreFile=/path/to/smart_android.jks
releaseStorePassword=...
releaseKeyAlias=smartandroid
releaseKeyPassword=...

서명 정보가 없으면 릴리스 빌드는 서명 없이 나온다. 그 APK는 기기에 설치되지 않는다.

처음 켠 뒤 할 일

  1. 앱 실행 → 위쪽 빨간 카드의 설정 열기 → 목록에서 이 앱을 켠다
  2. 블루투스 권한을 허용한다

기본 매크로 10개가 이미 깔려 있다. 다른 기기에서 쓴다면 AdGuard 매크로의 추가값(자동화 비밀번호)과 차량 매크로의 기기를 자기 것으로 바꿔야 한다.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages