feat: implement android notification cancellation
This commit is contained in:
parent
4c377a2f20
commit
6449040e61
|
@ -31,4 +31,8 @@ public class NotificationHelper {
|
||||||
NotificationManager notificationManager = ctx.getSystemService(NotificationManager.class);
|
NotificationManager notificationManager = ctx.getSystemService(NotificationManager.class);
|
||||||
notificationManager.notify(notificationID, builder.build());
|
notificationManager.notify(notificationID, builder.build());
|
||||||
}
|
}
|
||||||
|
public static void cancelNotification(Context ctx, int notificationID) {
|
||||||
|
NotificationManager notificationManager = ctx.getSystemService(NotificationManager.class);
|
||||||
|
notificationManager.cancel(notificationID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@ import (
|
||||||
"github.com/tailscale/tailscale-android/jni"
|
"github.com/tailscale/tailscale-android/jni"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
helperClass = "ht/sr/git/whereswaldon/niotify/NotificationHelper"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
idlock sync.Mutex
|
idlock sync.Mutex
|
||||||
nextNotificationID int32
|
nextNotificationID int32
|
||||||
|
@ -21,15 +25,20 @@ func nextID() int32 {
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotificationChannel represents a stream of notifications that an application
|
||||||
|
// provisions on android. Such streams can be selectively enabled and disabled
|
||||||
|
// by the user, and should be used for different purposes.
|
||||||
type NotificationChannel struct {
|
type NotificationChannel struct {
|
||||||
id string
|
id string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewChannel creates a new notification channel identified by the provided id
|
||||||
|
// and with the given user-visible name and description.
|
||||||
func NewChannel(id, name, description string) (*NotificationChannel, error) {
|
func NewChannel(id, name, description string) (*NotificationChannel, error) {
|
||||||
if err := jni.Do(jni.JVMFor(app.JavaVM()), func(env jni.Env) error {
|
if err := jni.Do(jni.JVMFor(app.JavaVM()), func(env jni.Env) error {
|
||||||
appCtx := jni.Object(app.AppContext())
|
appCtx := jni.Object(app.AppContext())
|
||||||
classLoader := jni.ClassLoaderFor(env, appCtx)
|
classLoader := jni.ClassLoaderFor(env, appCtx)
|
||||||
notifyClass, err := jni.LoadClass(env, classLoader, "ht/sr/git/whereswaldon/niotify/NotificationHelper")
|
notifyClass, err := jni.LoadClass(env, classLoader, helperClass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -51,16 +60,19 @@ func NewChannel(id, name, description string) (*NotificationChannel, error) {
|
||||||
return nc, nil
|
return nc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notification represents a notification that has been requested to be shown to the user.
|
||||||
|
// This type provides methods to cancel or update the contents of the notification.
|
||||||
type Notification struct {
|
type Notification struct {
|
||||||
id int32
|
id int32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send creates a new Notification and requests that it be displayed on this channel.
|
||||||
func (nc *NotificationChannel) Send(title, text string) (*Notification, error) {
|
func (nc *NotificationChannel) Send(title, text string) (*Notification, error) {
|
||||||
notificationID := nextID()
|
notificationID := nextID()
|
||||||
if err := jni.Do(jni.JVMFor(app.JavaVM()), func(env jni.Env) error {
|
if err := jni.Do(jni.JVMFor(app.JavaVM()), func(env jni.Env) error {
|
||||||
appCtx := jni.Object(app.AppContext())
|
appCtx := jni.Object(app.AppContext())
|
||||||
classLoader := jni.ClassLoaderFor(env, appCtx)
|
classLoader := jni.ClassLoaderFor(env, appCtx)
|
||||||
notifyClass, err := jni.LoadClass(env, classLoader, "ht/sr/git/whereswaldon/niotify/NotificationHelper")
|
notifyClass, err := jni.LoadClass(env, classLoader, helperClass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -74,9 +86,27 @@ func (nc *NotificationChannel) Send(title, text string) (*Notification, error) {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, fmt.Errorf("failed creating notification channel: %w", err)
|
return nil, fmt.Errorf("failed sending notification: %w", err)
|
||||||
}
|
}
|
||||||
return &Notification{
|
return &Notification{
|
||||||
id: notificationID,
|
id: notificationID,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cancel removes a previously created notification from display.
|
||||||
|
func (n *Notification) Cancel() error {
|
||||||
|
notificationID := n.id
|
||||||
|
if err := jni.Do(jni.JVMFor(app.JavaVM()), func(env jni.Env) error {
|
||||||
|
appCtx := jni.Object(app.AppContext())
|
||||||
|
classLoader := jni.ClassLoaderFor(env, appCtx)
|
||||||
|
notifyClass, err := jni.LoadClass(env, classLoader, helperClass)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newChannelMethod := jni.GetStaticMethodID(env, notifyClass, "cancelNotification", "(Landroid/content/Context;I)V")
|
||||||
|
return jni.CallStaticVoidMethod(env, notifyClass, newChannelMethod, jni.Value(app.AppContext()), jni.Value(notificationID))
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("failed cancelling notification: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"log"
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
"gioui.org/app"
|
"gioui.org/app"
|
||||||
"gioui.org/io/system"
|
"gioui.org/io/system"
|
||||||
|
@ -62,6 +63,10 @@ func loop(w *app.Window) error {
|
||||||
log.Printf("notification send failed: %v", err)
|
log.Printf("notification send failed: %v", err)
|
||||||
}
|
}
|
||||||
log.Println(notif)
|
log.Println(notif)
|
||||||
|
time.Sleep(time.Second * 10)
|
||||||
|
if err := notif.Cancel(); err != nil {
|
||||||
|
log.Printf("failed cancelling: %v", err)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user