FishNet is an on-device Android notification security app. It classifies notifications as useful, ad/promotional, spam, scam, or phishing, and can auto-dismiss unwanted promotional notifications.
- Scans notifications in real time using
NotificationListenerService. - Runs startup scans when:
- listener connects
- app starts
- device reboots (if protection is enabled)
- Startup summary now enforces:
useful = scanned - phishing - scam - irrelevant- so every scanned notification is counted.
SAFE_USEFULIRRELEVANT_ADSPAMSCAMPHISHING
IRRELEVANT_ADnotifications can be dismissed based on:- auto-block switch
- per-app policy
- aggressive mode
- Aggressive mode blocks:
IRRELEVANT_AD,SPAM,SCAM,PHISHING. - Promotional notifications are treated with strict promo blocking:
- non-transactional notifications are force-classified as ad/promotional and removed.
- Pre-existing promotional notifications in the tray are also removed during startup scan.
- WhatsApp handling:
- default path is useful
- only WhatsApp ad-like messages from unknown numbers are blocked
- known-contact WhatsApp messages are not blocked by this rule
- Phishing alert notification is shown only when phishing risk is
>= 60%. - Phishing subtype labels are shown only when risk is
> 50%. - Scam detection shows a dedicated scam alert notification.
- Tapping FishNet alerts opens the app.
Main dashboard shows:
- notifications scanned today
- phishing today
- scam today
- spam today
- total ads blocked today
- ads blocked today history (dropdown list)
- ad suppression efficiency
- risk meter
- last detected threat
- Every blocked ad is stored temporarily in local storage.
- History retention is 24 hours.
- Old entries are pruned automatically.
- UI count and dropdown list are sourced from the same history store to avoid mismatch.
FishNet uses hybrid detection, not ML-only:
- Extracts signals from text:
- URLs, urgency, action verbs, credential/payment cues
- Runs deterministic rule engines:
- ad rule engine
- scam logic
- spam frequency/repeat checks
- email-specific threat logic
- Runs on-device ML scoring:
- ONNX model (
model_int8.onnx) - tokenizer (
tokenizer.json)
- Combines signals in risk engine:
- ML score + signal strength + domain risk + app/tier context
- Applies strict final gates:
- phishing requires multiple conditions, not only model score
- subtype and alert visibility are risk-gated
MainActivity: protection toggles + metricsHistoryActivity: stored scan resultsSettingsActivity: aggressive mode, confidence threshold, clear history, export logs
BootCompletedReceiver listens to:
BOOT_COMPLETEDLOCKED_BOOT_COMPLETEDMY_PACKAGE_REPLACED
When enabled, it requests notification listener rebind and triggers startup scan.
android.permission.POST_NOTIFICATIONSandroid.permission.READ_CONTACTSandroid.permission.RECEIVE_BOOT_COMPLETED- notification listener access (user-enabled in system settings)
- Kotlin
- Android SDK
- ONNX Runtime
- Room
- Coroutines + StateFlow
minSdk = 26targetSdk = 36compileSdk = 36
From android_app/:
.\gradlew.bat :app:assembleDebugRelease APK:
.\gradlew.bat :app:assembleReleaseOutput:
android_app/app/build/outputs/apk/release/app-release.apk