diff --git a/android/NotificationHelper.java b/android/NotificationHelper.java index 0e1335b..cfd9874 100644 --- a/android/NotificationHelper.java +++ b/android/NotificationHelper.java @@ -21,4 +21,14 @@ public class NotificationHelper { Log.e(tag,String.format("manager: %s",notificationManager)); notificationManager.createNotificationChannel(channel); } + public static void sendNotification(Context ctx, String channelID, int notificationID, String title, String text) { + Notification.Builder builder = new Notification.Builder(ctx, channelID) + .setContentTitle(title) + .setSmallIcon(Icon.createWithBitmap(Bitmap.createBitmap(1,1,Bitmap.Config.ALPHA_8))) + .setContentText(text) + .setPriority(Notification.PRIORITY_DEFAULT); + + NotificationManager notificationManager = ctx.getSystemService(NotificationManager.class); + notificationManager.notify(notificationID, builder.build()); + } } diff --git a/android/notify_android.go b/android/notify_android.go index 43fba09..2c12ea8 100644 --- a/android/notify_android.go +++ b/android/notify_android.go @@ -2,11 +2,25 @@ package android import ( "fmt" + "sync" "gioui.org/app" "github.com/tailscale/tailscale-android/jni" ) +var ( + idlock sync.Mutex + nextNotificationID int32 +) + +func nextID() int32 { + idlock.Lock() + defer idlock.Unlock() + id := nextNotificationID + nextNotificationID++ + return id +} + type NotificationChannel struct { id string } @@ -36,3 +50,33 @@ func NewChannel(id, name, description string) (*NotificationChannel, error) { } return nc, nil } + +type Notification struct { + id int32 +} + +func (nc *NotificationChannel) Send(title, text string) (*Notification, error) { + notificationID := nextID() + 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, "ht/sr/git/whereswaldon/niotify/NotificationHelper") + if err != nil { + return err + } + newChannelMethod := jni.GetStaticMethodID(env, notifyClass, "sendNotification", "(Landroid/content/Context;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V") + jtitle := jni.Value(jni.JavaString(env, title)) + jtext := jni.Value(jni.JavaString(env, text)) + jID := jni.Value(jni.JavaString(env, nc.id)) + err = jni.CallStaticVoidMethod(env, notifyClass, newChannelMethod, jni.Value(app.AppContext()), jID, jni.Value(notificationID), jtitle, jtext) + if err != nil { + return err + } + return nil + }); err != nil { + return nil, fmt.Errorf("failed creating notification channel: %w", err) + } + return &Notification{ + id: notificationID, + }, nil +} diff --git a/example/hello.go b/example/hello.go index c9e3a6f..3dab691 100644 --- a/example/hello.go +++ b/example/hello.go @@ -21,7 +21,6 @@ import ( //go:generate javac -target 1.8 -source 1.8 -bootclasspath $ANDROID_HOME/platforms/android-29/android.jar ../android/NotificationHelper.java //go:generate jar cf NotificationHelper.jar ../android/NotificationHelper.class -//go:generate rm ../android/NotificationHelper.class func main() { go func() { @@ -30,19 +29,13 @@ func main() { log.Fatal(err) } }() - go func() { - channel, err := android.NewChannel("CHANNEL", "hello", "description") - if err != nil { - log.Printf("channel creation failed: %v", err) - } - log.Println(channel) - }() app.Main() } func loop(w *app.Window) error { th := material.NewTheme(gofont.Collection()) var ops op.Ops + first := true for { e := <-w.Events() switch e := e.(type) { @@ -56,6 +49,21 @@ func loop(w *app.Window) error { l.Alignment = text.Middle l.Layout(gtx) e.Frame(gtx.Ops) + if first { + first = false + go func() { + channel, err := android.NewChannel("CHANNEL", "hello", "description") + if err != nil { + log.Printf("channel creation failed: %v", err) + } + log.Println(channel) + notif, err := channel.Send("hello!", "IS GIO OUT THERE?") + if err != nil { + log.Printf("notification send failed: %v", err) + } + log.Println(notif) + }() + } } } }