The Notification Listener plugin receives callbacks when notifications are posted or removed on the device. It lets your Go code react to incoming notifications from any app.

Setup

The notification listener plugin is already registered in the default AppTemplate.

Android Manifest

The app must declare a NotificationListenerService and the user must grant notification access in system settings.

<service
    android:name="com.sweetjuice.pkg.notifications.SweetJuiceNotificationListener"
    android:label="@string/app_name"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
    android:exported="false">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

Use the Special Permissions plugin to open the notification access settings screen:

import "github.com/sweet-juice/sweetjuice/plugins/special"

special.RequestNotificationAccess()

API

notification_listener.NewPlugin() *NotificationListenerPlugin

Creates a new notification listener plugin instance.

(*NotificationListenerPlugin).OnPosted(key string, handler NotificationHandler)

Registers a handler that is called when a notification is posted.

(*NotificationListenerPlugin).OnRemoved(key string, handler NotificationHandler)

Registers a handler that is called when a notification is removed.

(*NotificationListenerPlugin).OnGranted(key string, handler GrantedHandler)

Registers a handler that is called when notification access is granted by the user.

type GrantedHandler func()

Types

Notification

type Notification struct {
    PackageName string `json:"package_name"`
    ID          int    `json:"id"`
    Title       string `json:"title,omitempty"`
    Text        string `json:"text,omitempty"`
    IsOngoing   bool   `json:"is_ongoing"`
    Timestamp   int64  `json:"timestamp"`
}

NotificationHandler

type NotificationHandler func(Notification) error

GrantedHandler

type GrantedHandler func()

Example

import (
    "fmt"
    "github.com/sweet-juice/sweetjuice/plugins/notification_listener"
)

plugin := notification_listener.NewPlugin()

plugin.OnPosted("default", func(n notification_listener.Notification) error {
    fmt.Printf("Notification from %s: %s - %s\n", n.PackageName, n.Title, n.Text)
    return nil
})

plugin.OnRemoved("default", func(n notification_listener.Notification) error {
    fmt.Printf("Notification removed from %s\n", n.PackageName)
    return nil
})

plugin.OnGranted("default", func() {
    fmt.Println("Notification access granted")
})

Events

notification-listener:posted

Fired when a notification is posted. Payload:

{
  "package_name": "com.example.app",
  "id": 42,
  "title": "Hello",
  "text": "World",
  "is_ongoing": false,
  "timestamp": 1722345678901
}

notification-listener:removed

Fired when a notification is removed. Payload has the same shape as posted.

notification-listener:granted

Fired when notification access is granted. No payload required.

Android Notes

  • The user must grant Notification access in system settings before the listener receives events.
  • The listener runs even when the app UI is not visible.
  • Title and Text are extracted from Notification.EXTRA_TITLE and Notification.EXTRA_TEXT when available.
  • Some notifications may not expose text if the posting app suppresses it.