App Android que bloqueia SMS Flash (Class 0) — aquelas mensagens que aparecem de repente na tela inteira, muito usadas em spam e phishing. Sem root.
O app fecha automaticamente o pop-up do Flash SMS no instante em que ele aparece.
SMS Class 0 ("Flash SMS") são mensagens que o próprio sistema Android exibe
imediatamente em cima de tudo, em vez de guardá-las na caixa de entrada (padrão
GSM 3GPP TS 23.040, campo TP-DCS com classe = 0). Operadoras usam para avisos,
mas golpistas abusam disso — ex.: "sua linha será desativada, recarregue em
[link falso]".
Em um celular sem root, nenhum app consegue impedir o pop-up de aparecer — quem o desenha é o sistema, antes de qualquer app ser avisado. A única solução possível é fechá-lo instantaneamente, e é isso que este app faz:
- Um AccessibilityService detecta quando a tela de Class 0 aparece e a fecha na hora (o pop-up pisca por uma fração de segundo e some).
- A detecção é pelo tipo da janela, não pelo conteúdo — não depende das palavras da mensagem, então é à prova de disfarce.
- Não lê, não envia e não armazena nenhum SMS. Funciona 100% offline, sem anúncios. A única permissão usada é a de Acessibilidade.
Feito e testado no Samsung Galaxy A73 5G (One UI / Android 13). A detecção está afinada para a tela de Class 0 do Samsung:
com.samsung.android.messaging / ...ui.view.classzero.ClassZeroActivity
Em aparelhos de outros fabricantes (ou versões diferentes do One UI) pode não funcionar sem reajuste. Veja Adaptar para outro aparelho.
- Baixe o APK mais recente em Releases.
- Instale (o Android vai pedir para permitir instalar de fontes desconhecidas).
- Ative a acessibilidade pela própria tela do sistema (assim fica permanente e sobrevive a reinicializações): Configurações → Acessibilidade → Apps instalados → Flash SMS Blocker → ligar (em inglês: Settings → Accessibility → Installed apps).
- Confira no app: o status deve ficar verde "Proteção ativa". Pronto! 🎉
Se aparecer o aviso "Restricted setting" (Samsung/Android 13+ bloqueia a acessibilidade de apps instalados fora da loja): vá em Configurações → Apps → Flash SMS Blocker → ⋮ → Permitir configurações restritas ("Allow restricted settings") e repita o passo 3.
O One UI adormece apps em segundo plano para poupar bateria — e isso pode fazer o app perder um Flash SMS. Garanta que ele fique sempre pronto:
Configurações → Bateria → Limites de uso em segundo plano → confira que o Flash SMS Blocker não está em "Apps em suspensão" ("Sleeping apps") nem em "Apps em suspensão profunda" ("Deep sleeping apps") — ou adicione-o em "Apps que nunca entram em suspensão" ("Never sleeping apps").
O app é leve (funciona por eventos, sem internet, sem notificação fixa) — o consumo de bateria é desprezível.
Apps bancários bloqueiam o próprio uso quando detectam qualquer serviço de acessibilidade desconhecido ativo — é a defesa deles contra trojans de Pix, e eles reagem à capacidade do serviço, não ao que ele faz. Se o seu banco reclamar do Flash SMS Blocker:
- No app, abra ⋮ → Pausar bloqueio (apps de banco) — o serviço de acessibilidade é desativado de verdade (não é só "ignorar eventos"; é o que o antifraude verifica).
- Use o app do banco normalmente.
- Depois, toque no card "⏸ Bloqueio pausado" e reative o serviço na tela de acessibilidade (o Android não permite que um app se reative sozinho).
Não coleta, não transmite e não armazena nenhum dado pessoal ou mensagem. Todo o processamento é local. Sem rastreadores, sem anúncios, sem internet.
A detecção de cada aparelho fica numa lista de regras em FlashPopupRule.KNOWN
(app/src/main/java/com/flashblocker/FlashPopupRule.java). Suportar um aparelho
novo é, na maioria dos casos, adicionar uma linha lá.
1. Descubra a identidade do pop-up — sem recompilar:
- No app, abra ⋮ → Modo aprendizado (liga). Nesse modo o app não fecha nada
— só registra cada janela nova no histórico (e no logcat):
adb logcat -s FlashBlocker/LEARN - Receba um Flash SMS e procure o bloco
==== NEW WINDOW ====com opackage, aclasse osbuttonsdo pop-up. (Sem PC, dá pra ler direto no histórico do app.) - Desligue o Modo aprendizado depois.
2. Adicione a regra em FlashPopupRule.KNOWN:
new FlashPopupRule(
"Nome do aparelho/ROM",
"com.pacote.do.app.de.mensagens", // package capturado
"ClassZeroActivity", // trecho da class capturada
"class 0", // marcador no texto (ou null)
new String[] { "cancel", "cancelar", "dismiss" }) // botão de descartarRecompile e pronto. Se o aparelho precisar de lógica de detecção diferente, dá
para estender FlashPopupRule e sobrescrever matches(...).
Pull requests com o mapeamento de outros aparelhos são muito bem-vindos! 🙌
Projeto em Java puro, sem dependências externas. SDK 34, minSdk 24, JDK 17.
Android Studio: File → Open na pasta do projeto e Build → Build APK(s).
Linha de comando (Gradle wrapper): precisa só de JDK 17 e do Android SDK
(aponte via ANDROID_HOME ou crie um local.properties com sdk.dir=...):
./gradlew assembleDebug
# saída: app/build/outputs/apk/debug/app-debug.apkTestes de unidade (JUnit, rodam na JVM, sem aparelho) — a cobertura das classes
de lógica (FlashPopupRule e BlockStats) é exigida em 100% de linhas e branches;
o build falha abaixo disso:
./gradlew testDebugUnitTest jacocoCoverageVerification
# relatório de cobertura (HTML):
./gradlew jacocoTestReport # app/build/reports/jacoco/jacocoTestReport/html/index.htmlAlternativa sem Gradle — build leve via aapt/d8, precisa do Android SDK
(platform android-34 + build-tools) e JDK 17. São um script por etapa
(todos na raiz do projeto; common.sh guarda o que é compartilhado):
export ANDROID_HOME=/caminho/para/Android/Sdk
./build.sh # compila → build/app-aligned.apk (NÃO assinado)
./sign.sh # assina com chave debug → build/flash-sms-blocker.apk
./sign.sh release # ou assina com a chave durável (pede a senha no terminal)
./install.sh # instala no celular (auto: Wi-Fi se houver, senão USB)
./install.sh usb # só USB | ./install.sh wifi # só Wi-FiE o deploy.sh roda a esteira inteira (build → sign → install) num comando:
./deploy.sh # debug + dispositivo automático
./deploy.sh release wifi # release assinado, instalado pelo Wi-FiO install.sh também reativa o serviço de acessibilidade (que o Android
desliga em todo update) e confere que ele voltou.
Os scripts buildam sem Gradle e sem internet — mas exigem o SDK já instalado:
| Requisito | Para quê |
|---|---|
| JDK 17 | javac e keytool |
Android SDK — platform android-34 |
android.jar (compilar contra a API 34) |
Android SDK — build-tools (recente) |
aapt, d8, zipalign, apksigner |
| bash | rodar o script (Linux/Mac; no Windows via WSL ou Git Bash) |
Não precisa de Gradle, Android Studio nem internet (uma vez que o SDK esteja instalado).
Se você já usa o Android Studio, tudo isso já vem instalado (via SDK Manager) —
basta apontar o ANDROID_HOME para o SDK. Sem o Android Studio, instale pela linha
de comando:
1. JDK 17
# Debian/Ubuntu
sudo apt install openjdk-17-jdk
# Arch/Manjaro
sudo pacman -S jdk17-openjdk
# macOS (Homebrew)
brew install openjdk@17
# ou, multiplataforma, via SDKMAN (https://sdkman.io):
sdk install java 17.0.11-tem2. Android SDK (command-line tools, sem Android Studio)
- Baixe o "Command line tools" em https://developer.android.com/studio#command-tools.
- Organize em
$ANDROID_HOME/cmdline-tools/latest/:export ANDROID_HOME="$HOME/Android/Sdk" mkdir -p "$ANDROID_HOME/cmdline-tools" unzip commandlinetools-*.zip -d "$ANDROID_HOME/cmdline-tools" mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest"
- Instale os componentes e aceite as licenças:
sdkmanager "platform-tools" "platforms;android-34" "build-tools;34.0.0" sdkmanager --licenses
Adicione ao seu ~/.bashrc/~/.zshrc para não repetir:
export ANDROID_HOME="$HOME/Android/Sdk". Feito isso, os scripts funcionam.
Os dois builds acima assinam com um keystore de debug descartável — servem para
testar, mas o Android só aceita atualizar um app instalado se o APK novo tiver a
mesma assinatura do anterior (INSTALL_FAILED_UPDATE_INCOMPATIBLE caso contrário).
Por isso o APK publicado em Releases é assinado com uma chave durável, guardada
fora do repositório e protegida por senha — a senha não está escrita em lugar
nenhum (nem deve estar: quem a tivesse poderia assinar uma "atualização" maliciosa).
Criar a chave (uma única vez):
mkdir -p ~/.keystores
keytool -genkeypair -keyalg RSA -keysize 2048 -validity 10000 \
-keystore ~/.keystores/flash-sms-blocker.jks \
-alias flash -dname "CN=Flash SMS Blocker"
# ele pergunta a senha; guarde-a num gerenciador de senhas — não há como recuperá-laRelease sem Gradle — o sign.sh release assina com a chave durável; o
apksigner pergunta a senha no terminal (ela não passa por variável de ambiente
nem fica no histórico do shell):
./deploy.sh release wifi # compila, assina, instala e reativa a acessibilidade
# ou por etapas: ./build.sh && ./sign.sh release && ./install.sh wifiO caminho do keystore é ~/.keystores/flash-sms-blocker.jks por padrão (mude com
RELEASE_KEYSTORE=...); se ele tiver mais de um alias, defina RELEASE_KEY_ALIAS.
Build release com o Gradle — o assembleRelease assina sozinho se encontrar o
keystore e a senha nas variáveis de ambiente (sem elas, gera APK não assinado —
contribuidores não precisam configurar nada):
export RELEASE_KEYSTORE_PASSWORD='...' # e opcionalmente RELEASE_KEYSTORE,
./gradlew assembleRelease # RELEASE_KEY_ALIAS, RELEASE_KEY_PASSWORD
# saída: app/build/outputs/apk/release/app-release.apkNotas:
- Um build de debug não instala por cima de um release (assinaturas diferentes): ou assine o build com a chave release, ou desinstale antes — desinstalar apaga as estatísticas e desativa o serviço de acessibilidade, que precisa ser reativado.
- Nunca comite o
.jksnem a senha no repositório.
Pré-requisito: celular em modo desenvolvedor com a depuração USB ligada (Configurações → Opções do desenvolvedor).
Jeito recomendado — o install.sh instala e reativa o serviço de
acessibilidade num comando só:
./install.sh # automático: Wi-Fi se houver, senão USB
./install.sh usb # só USB
./install.sh wifi # só Wi-Fi (ativa a partir do USB ou de PHONE_IP=<ip>)Ele instala o build/flash-sms-blocker.apk já assinado (a assinatura é
preservada — pode ter sido assinado em outro terminal). Para compilar, assinar
e instalar tudo de uma vez: ./deploy.sh release wifi.
Na mão (ex.: APK buildado pelo Gradle):
adb devices # o aparelho deve aparecer como "device"
adb install -r build/flash-sms-blocker.apk # (ou app/build/outputs/apk/... no Gradle)Gotchas (todos vistos na prática no A73):
-
Samsung bloqueia sideload por adb (
INSTALL_FAILED_VERIFICATION_FAILURE): desligue o Auto Blocker (Configurações → Segurança e privacidade) e o Verificar apps via USB (Opções do desenvolvedor). -
O celular em modo tethering USB some do adb — deixe o USB em transferência de arquivos.
-
INSTALL_FAILED_UPDATE_INCOMPATIBLE: o APK instalado foi assinado com outra chave (ex.: havia um build debug e você está enviando um release). Não tem contorno — desinstale e instale de novo (isso zera as estatísticas e desativa o serviço de acessibilidade):adb uninstall com.flashblocker adb install build/flash-sms-blocker.apk
-
Atualizar o app desativa o serviço de acessibilidade (comportamento do Android) — depois de todo
adb install -rmanual, confira o card de status no app ou reative pelo adb (comandos abaixo). O./install.shjá faz isso sozinho. -
adb pelo Wi-Fi (sem cabo): plugue o USB uma vez e rode:
adb tcpip 5555 # liga o modo TCP (dura até reiniciar o celular) adb shell ip addr show wlan0 # anote o IP do celular (linha "inet ...") adb connect IP_DO_CELULAR:5555 # agora pode desplugar o USB
Nas próximas vezes (mesmo boot), basta o
adb connect. Com o celular em duas conexões ao mesmo tempo (USB + Wi-Fi), direcione os comandos comadb -s IP:5555 .... -
Para reativar o serviço de acessibilidade sem mexer no aparelho:
adb shell settings put secure enabled_accessibility_services \ com.flashblocker/com.flashblocker.FlashSmsAccessibilityService adb shell settings put secure accessibility_enabled 1 # confirmar: adb shell dumpsys accessibility | grep 'Flash SMS Blocker'
Software fornecido "como está", sem garantias (veja a licença). Use por sua conta e risco. Este projeto não é afiliado à Samsung, Google, Vivo ou a qualquer operadora ou empresa; nomes de terceiros aparecem apenas como exemplo.
MIT © 2026 Rafael (rdmsilva)