#22329: Android : Add Notification Intelligence -- cross-app AI triage
app: android
size: XL
Cluster:
macOS Notification and Menu Fixes
## Summary
- Adds `NotificationListenerService` on Android to capture notifications from all apps (with explicit user permission) and stream them to the OpenClaw gateway for AI-powered triage
- Adds `notification-intelligence` gateway extension that classifies notifications by urgency, stores them in-memory, and exposes `/notifications digest`, a `notification_triage` agent tool, and a `notifications.batch` gateway method
- Adds `notifications.dismiss` and `notifications.list` invoke commands so the gateway can manage notifications on the phone remotely
## Problem Statement
Every AI assistant today — Siri, Google Assistant, Alexa, Copilot — is sandboxed. They can only see their own app's notifications. Meanwhile, the average user has 40+ apps generating notifications across Slack, WhatsApp, Gmail, banking, deliveries, social media, and more. The result: constant context-switching, notification fatigue, and missed critical alerts buried under noise.
No existing AI assistant can look across all your apps and tell you: *"You have 47 notifications. 3 need attention right now. The rest can wait."*
## Why OpenClaw, and Why Android
Android is the only mobile OS that provides `NotificationListenerService` — a system API that lets an app (with explicit user permission) read notifications from *all* other apps. iOS does not allow this.
OpenClaw is the only AI assistant where this data stays entirely on the user's own infrastructure. Unlike cloud AI assistants that would need to upload notification content to third-party servers, OpenClaw's gateway is self-hosted. Notification content travels over the existing TLS WebSocket to *your* gateway, gets triaged in-memory (never written to disk), and expires after 1 hour.
This builds on the vision @steipete laid out in VISION.md — *"a personal assistant that is easy to use, supports a wide range of platforms, and respects privacy and security"* — and extends the phone-as-node architecture that Peter and the team designed for the iOS and Android companion apps.
## What This Enables
**For users:**
- `/notifications digest` — AI-summarized notification overview, grouped by urgency
- Ask the agent *"do I have anything urgent on my phone?"* and it answers using the `notification_triage` tool
- Gateway can dismiss low-priority notifications remotely via `notifications.dismiss`
**For the platform:**
- First cross-app AI notification layer that exists anywhere, on any platform
- Proof that OpenClaw's gateway-node architecture can do things no sandboxed assistant can
- Foundation for future features: smart DND, auto-dismiss rules, notification-triggered automations
## Privacy: 7 Layers of Defense
| Layer | Protection |
|-------|-----------|
| Android system | User must manually enable Notification Access in Settings (cannot be granted programmatically) |
| App setting | `notifications.enabled` defaults to **OFF** — requires explicit toggle |
| Filter | Banking, health, authenticator, 2FA, OTP apps auto-excluded by package name pattern |
| Data minimization | Only title + text (capped at 500 chars) extracted. No extras, bitmaps, or actions |
| Transport | Existing TLS-encrypted WebSocket |
| Preferences | EncryptedSharedPreferences (AES-256-GCM) |
| Gateway storage | In-memory only with 1-hour TTL. **Nothing written to disk** |
## Architecture
```
Android Gateway
┌──────────────────────┐ ┌─────────────────────────────┐
│ NotificationListener │──extract──► │ │
│ Service (OS-level) │ │ │
│ ↓ (pre-buffer) │ │ │
│ NotificationFilter │ │ │
│ ↓ (dedup by ID) │ │ │
│ NotificationBatcher │──30s batch──► │ notifications.batch method │
│ ↓ (retry x3) │ (RPC) │ ↓ │
│ NotificationHandler │◄──dismiss── │ notification-intelligence │
│ (invoke commands) │ (invoke) │ ├─ heuristic triage │
└──────────────────────┘ │ ├─ deduped store (TTL) │
│ ├─ /notifications command │
│ └─ notification_triage │
│ tool (for agent) │
└─────────────────────────────┘
```
## Files Changed (20 files, +1,119 lines)
**New Android files (6):**
- `notification/NotificationModels.kt` — `@Serializable` data classes
- `notification/NotificationFilter.kt` — Per-app allow/blocklist + sensitive app auto-exclusion
- `notification/NotificationBatcher.kt` — Deduped batching with retry-on-failure
- `notification/OpenClawNotificationListener.kt` — System service with pre-buffer for race-free startup
- `node/NotificationListenerBridge.kt` — Bridges service lifecycle with NodeRuntime
- `node/NotificationHandler.kt` — Handles `notifications.dismiss` / `notifications.list` invoke commands
**Modified Android files (8):**
- `OpenClawProtocolConstants.kt` — `Notifications` capability + command enum
- `AndroidManifest.xml` — Service declaration with `BIND_NOTIFICATION_LISTENER_SERVICE`
- `SecurePrefs.kt` — `notificationsEnabled` + `notificationsBatchWindowSec` preferences
- `ConnectionManager.kt` — Advertise capability + commands
- `InvokeDispatcher.kt` — Pre-dispatch validation + dispatch routes
- `NodeRuntime.kt` — Wire filter, bridge, handler; init-block activation
- `MainViewModel.kt` — Expose StateFlows
- `SettingsSheet.kt` — Notifications settings section
**New gateway extension (6):**
- `extensions/notification-intelligence/openclaw.plugin.json` — Plugin manifest
- `extensions/notification-intelligence/index.ts` — Gateway method, command, tool, GC service
- `extensions/notification-intelligence/src/types.ts` — TypeScript types
- `extensions/notification-intelligence/src/triage.ts` — Heuristic triage (zero LLM cost)
- `extensions/notification-intelligence/src/store.ts` — Deduped in-memory store with TTL
- `extensions/notification-intelligence/src/digest.ts` — Digest formatting
## Test Plan
- [x] Android debug build: `./gradlew :app:assembleDebug` — **PASS**
- [x] Install on emulator (API 36): `adb install` — **PASS**
- [x] App launches, main screen renders — **PASS**
- [x] Notifications section appears in Settings between Location and Screen — **PASS**
- [x] Toggle defaults to OFF — **PASS**
- [x] Toggling ON opens Android Notification Access system settings — **PASS**
- [x] "OpenClaw Node" listed in system notification listeners — **PASS**
- [x] Toggle state persists after returning from system settings — **PASS**
- [x] Conditional UI (Listener Status + privacy text) only shows when enabled — **PASS**
- [x] Listener Status correctly shows "Not connected" when system permission not yet granted — **PASS**
- [x] Bridge activation/deactivation logged in logcat (`OpenClawNotifBridge`) — **PASS**
- [x] Privacy notice text renders: "Banking, health, and authenticator apps are excluded..." — **PASS**
- [ ] End-to-end: grant notification access, verify batches arrive at gateway (requires running gateway)
- [ ] `/notifications digest` command returns formatted output
- [ ] `notification_triage` tool returns structured JSON
- [ ] Gateway build: `pnpm build`
- [ ] Gateway tests: `pnpm test`
cc @steipete — this builds on the phone-as-node architecture you designed. Would love your take on whether the privacy layers are sufficient and whether `notifications.batch` should go through `node.event` vs direct gateway method (went with direct RPC for ack semantics).
Most Similar PRs
#19828: feat: reply notifications for macOS and web UI
by fal3 · 2026-02-18
70.9%
#12234: gateway: incident tracking, recover command, and ciao ERR_SERVER_CL...
by levineam · 2026-02-09
70.1%
#13321: android/gateway: harden manual connect identity and A2UI UX
by m888m · 2026-02-10
69.0%
#8311: feat(gateway): add SYSTEM_COMMANDS to Android node allowlist
by ipv1337 · 2026-02-03
67.8%
#23326: fix(daemon): graceful degradation on unsupported platforms
by indistinctchatter604 · 2026-02-22
67.8%
#12635: Gateway: add inbound webhook dispatch framework
by jhs129 · 2026-02-09
66.9%
#18438: macOS: add in-app CLI + gateway install with reset support
by rimusz · 2026-02-16
66.4%
#11788: feat: inter-agent communication via CLI scripts
by jingkang0822 · 2026-02-08
66.3%
#23636: iOS: normalize watch quick actions and fix test signing
by mbelinky · 2026-02-22
66.2%
#8086: feat(security): Add prompt injection guard rail
by bobbythelobster · 2026-02-03
66.1%