Skip to content

Commit

Permalink
Get android notifications working.
Browse files Browse the repository at this point in the history
It's kindof MVP and could do with improvements, but it works down to API 16
  • Loading branch information
andydotxyz committed May 1, 2020
1 parent 6cc5819 commit 2089b56
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 2 deletions.
81 changes: 81 additions & 0 deletions app/app_mobile_and.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// +build !ci

// +build android

#include <android/log.h>
#include <jni.h>
#include <stdlib.h>

#define LOG_FATAL(...) __android_log_print(ANDROID_LOG_FATAL, "GoLog", __VA_ARGS__)

static jclass find_class(JNIEnv *env, const char *class_name) {
jclass clazz = (*env)->FindClass(env, class_name);
if (clazz == NULL) {
(*env)->ExceptionClear(env);
LOG_FATAL("cannot find %s", class_name);
return NULL;
}
return clazz;
}

static jmethodID find_method(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
jmethodID m = (*env)->GetMethodID(env, clazz, name, sig);
if (m == 0) {
(*env)->ExceptionClear(env);
LOG_FATAL("cannot find method %s %s", name, sig);
return 0;
}
return m;
}

static jmethodID find_static_method(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
jmethodID m = (*env)->GetStaticMethodID(env, clazz, name, sig);
if (m == 0) {
(*env)->ExceptionClear(env);
LOG_FATAL("cannot find method %s %s", name, sig);
return 0;
}
return m;
}

jobject getSystemService(uintptr_t jni_env, uintptr_t ctx, char *service) {
JNIEnv *env = (JNIEnv*)jni_env;
jstring serviceStr = (*env)->NewStringUTF(env, service);

jclass ctxClass = (*env)->GetObjectClass(env, ctx);
jmethodID getSystemService = find_method(env, ctxClass, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");

return (jobject)(*env)->CallObjectMethod(env, ctx, getSystemService, serviceStr);
}

int nextId = 1;

void sendNotification(uintptr_t java_vm, uintptr_t jni_env, uintptr_t ctx, char *title, char *body) {
JNIEnv *env = (JNIEnv*)jni_env;
jstring titleStr = (*env)->NewStringUTF(env, title);
jstring bodyStr = (*env)->NewStringUTF(env, body);

jclass cls = find_class(env, "android/app/Notification$Builder");
jmethodID constructor = find_method(env, cls, "<init>", "(Landroid/content/Context;)V");
jobject builder = (*env)->NewObject(env, cls, constructor, ctx);

jmethodID setContentTitle = find_method(env, cls, "setContentTitle", "(Ljava/lang/CharSequence;)Landroid/app/Notification$Builder;");
(*env)->CallObjectMethod(env, builder, setContentTitle, titleStr);

jmethodID setContentText = find_method(env, cls, "setContentText", "(Ljava/lang/CharSequence;)Landroid/app/Notification$Builder;");
(*env)->CallObjectMethod(env, builder, setContentText, bodyStr);

int iconID = 17629184; // constant of "unknown app icon"
jmethodID setSmallIcon = find_method(env, cls, "setSmallIcon", "(I)Landroid/app/Notification$Builder;");
(*env)->CallObjectMethod(env, builder, setSmallIcon, iconID);

jmethodID build = find_method(env, cls, "build", "()Landroid/app/Notification;");
jobject notif = (*env)->CallObjectMethod(env, builder, build);

jclass mgrCls = find_class(env, "android/app/NotificationManager");
jobject mgr = getSystemService(env, ctx, "notification");

jmethodID notify = find_method(env, mgrCls, "notify", "(ILandroid/app/Notification;)V");
(*env)->CallVoidMethod(env, mgr, notify, nextId, notif);
nextId++;
}
21 changes: 20 additions & 1 deletion app/app_mobile_and.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@

package app

/*
#cgo LDFLAGS: -landroid -llog
#include <stdlib.h>
void sendNotification(uintptr_t java_vm, uintptr_t jni_env, uintptr_t ctx, char *title, char *content);
*/
import "C"
import (
"log"
"net/url"
"os"
"unsafe"

mobileApp "github.com/fyne-io/mobile/app"

"fyne.io/fyne"
"fyne.io/fyne/theme"
Expand All @@ -25,7 +36,15 @@ func (app *fyneApp) OpenURL(url *url.URL) error {
}

func (app *fyneApp) SendNotification(notify *fyne.Notification) {
log.Println("NOT YET IMPLEMENTED") // TODO
titleStr := C.CString(notify.Title)
defer C.free(unsafe.Pointer(titleStr))
contentStr := C.CString(notify.Content)
defer C.free(unsafe.Pointer(contentStr))

mobileApp.RunOnJVM(func(vm, env, ctx uintptr) error {
C.sendNotification(C.uintptr_t(vm), C.uintptr_t(env), C.uintptr_t(ctx), titleStr, contentStr)
return nil
})
}

func rootConfigDir() string {
Expand Down
2 changes: 1 addition & 1 deletion cmd/fyne/internal/mobile/binres/binres.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ func UnmarshalXML(r io.Reader, withIcon bool) (*XML, error) {
Space: androidSchema,
Local: "targetSdkVersion",
},
Value: "28",
Value: "25",
},
},
}
Expand Down

0 comments on commit 2089b56

Please sign in to comment.