Mercurial > dwindows
comparison android/dw.cpp @ 2522:66c490aa719d
Android: Implement notifications, images on notifications incomplete.
Also detect the Android application ID, and generate one if not set
or detected. Also store the path as the application directory.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Sun, 09 May 2021 19:27:23 +0000 |
parents | 5f92284e2b08 |
children | 82cdb3ad7c25 |
comparison
equal
deleted
inserted
replaced
2521:5f92284e2b08 | 2522:66c490aa719d |
---|---|
34 extern "C" { | 34 extern "C" { |
35 #endif | 35 #endif |
36 | 36 |
37 #define DW_CLASS_NAME "org/dbsoft/dwindows/DWindows" | 37 #define DW_CLASS_NAME "org/dbsoft/dwindows/DWindows" |
38 | 38 |
39 static char _dw_app_id[_DW_APP_ID_SIZE+1]= {0}; | |
40 static char _dw_app_name[_DW_APP_ID_SIZE+1]= {0}; | |
41 static char _dw_exec_dir[MAX_PATH+1] = {0}; | |
42 | |
39 static pthread_key_t _dw_env_key; | 43 static pthread_key_t _dw_env_key; |
40 static HEV _dw_main_event; | 44 static HEV _dw_main_event; |
41 static JavaVM *_dw_jvm; | 45 static JavaVM *_dw_jvm; |
42 static jobject _dw_obj; | 46 static jobject _dw_obj; |
43 static jobject _dw_class_loader; | 47 static jobject _dw_class_loader; |
108 * to be called and return. | 112 * to be called and return. |
109 * Parameters: | 113 * Parameters: |
110 * path: The path to the Android app. | 114 * path: The path to the Android app. |
111 */ | 115 */ |
112 JNIEXPORT void JNICALL | 116 JNIEXPORT void JNICALL |
113 Java_org_dbsoft_dwindows_DWindows_dwindowsInit(JNIEnv* env, jobject obj, jstring path) | 117 Java_org_dbsoft_dwindows_DWindows_dwindowsInit(JNIEnv* env, jobject obj, jstring path, jstring appID) |
114 { | 118 { |
115 char *arg = strdup(env->GetStringUTFChars((jstring) path, NULL)); | 119 char *arg = strdup(env->GetStringUTFChars((jstring)path, NULL)); |
120 const char *appid = env->GetStringUTFChars((jstring)appID, NULL); | |
116 | 121 |
117 if(!_dw_main_event) | 122 if(!_dw_main_event) |
118 { | 123 { |
119 /* Save our class object pointer for later */ | 124 /* Save our class object pointer for later */ |
120 _dw_obj = env->NewGlobalRef(obj); | 125 _dw_obj = env->NewGlobalRef(obj); |
123 pthread_key_create(&_dw_env_key, NULL); | 128 pthread_key_create(&_dw_env_key, NULL); |
124 pthread_setspecific(_dw_env_key, env); | 129 pthread_setspecific(_dw_env_key, env); |
125 | 130 |
126 /* Create the dwmain event */ | 131 /* Create the dwmain event */ |
127 _dw_main_event = dw_event_new(); | 132 _dw_main_event = dw_event_new(); |
133 } | |
134 | |
135 if(arg) | |
136 { | |
137 /* Store the passed in path for dw_app_dir() */ | |
138 strncpy(_dw_exec_dir, arg, MAX_PATH); | |
139 } | |
140 if(appid) | |
141 { | |
142 /* Store our reported Android AppID */ | |
143 strncpy(_dw_app_id, appid, _DW_APP_ID_SIZE); | |
128 } | 144 } |
129 | 145 |
130 /* Launch the new thread to execute dwmain() */ | 146 /* Launch the new thread to execute dwmain() */ |
131 dw_thread_new((void *) _dw_main_launch, arg, 0); | 147 dw_thread_new((void *) _dw_main_launch, arg, 0); |
132 } | 148 } |
626 * Returns a pointer to a static buffer which contains the | 642 * Returns a pointer to a static buffer which contains the |
627 * private application data directory. | 643 * private application data directory. |
628 */ | 644 */ |
629 char * API dw_app_dir(void) | 645 char * API dw_app_dir(void) |
630 { | 646 { |
631 static char _dw_exec_dir[MAX_PATH+1] = {0}; | 647 /* The path is passed in via JNI dwindowsInit() */ |
632 /* Code to determine the execution directory here, | |
633 * some implementations make this variable global | |
634 * and determine the location in dw_init(). | |
635 */ | |
636 return _dw_exec_dir; | 648 return _dw_exec_dir; |
637 } | 649 } |
638 | 650 |
639 /* | 651 /* |
640 * Sets the application ID used by this Dynamic Windows application instance. | 652 * Sets the application ID used by this Dynamic Windows application instance. |
647 * DW_ERROR_GENERAL if the application ID is not allowed. | 659 * DW_ERROR_GENERAL if the application ID is not allowed. |
648 * Remarks: | 660 * Remarks: |
649 * This must be called before dw_init(). If dw_init() is called first | 661 * This must be called before dw_init(). If dw_init() is called first |
650 * it will create a unique ID in the form: org.dbsoft.dwindows.application | 662 * it will create a unique ID in the form: org.dbsoft.dwindows.application |
651 * or if the application name cannot be detected: org.dbsoft.dwindows.pid.# | 663 * or if the application name cannot be detected: org.dbsoft.dwindows.pid.# |
652 * The appname is only required on Windows. If NULL is passed the detected | 664 * The appname is used on Windows and Android. If NULL is passed the |
653 * application name will be used, but a prettier name may be desired. | 665 * detected name will be used, but a prettier name may be desired. |
654 */ | 666 */ |
655 int API dw_app_id_set(const char *appid, const char *appname) | 667 int API dw_app_id_set(const char *appid, const char *appname) |
656 { | 668 { |
657 return DW_ERROR_UNKNOWN; | 669 if(appid) |
670 strncpy(_dw_app_id, appid, _DW_APP_ID_SIZE); | |
671 if(appname) | |
672 strncpy(_dw_app_name, appname, _DW_APP_ID_SIZE); | |
673 return DW_ERROR_NONE; | |
658 } | 674 } |
659 | 675 |
660 /* | 676 /* |
661 * Displays a debug message on the console... | 677 * Displays a debug message on the console... |
662 * Parameters: | 678 * Parameters: |
4235 * Parameters: | 4251 * Parameters: |
4236 * env: Pointer to a DWEnv struct. | 4252 * env: Pointer to a DWEnv struct. |
4237 */ | 4253 */ |
4238 void API dw_environment_query(DWEnv *env) | 4254 void API dw_environment_query(DWEnv *env) |
4239 { | 4255 { |
4240 strcpy(env->osName, "Unknown"); | 4256 strcpy(env->osName, "Android"); |
4241 | 4257 |
4242 strcpy(env->buildDate, __DATE__); | 4258 strcpy(env->buildDate, __DATE__); |
4243 strcpy(env->buildTime, __TIME__); | 4259 strcpy(env->buildTime, __TIME__); |
4244 env->DWMajorVersion = DW_MAJOR_VERSION; | 4260 env->DWMajorVersion = DW_MAJOR_VERSION; |
4245 env->DWMinorVersion = DW_MINOR_VERSION; | 4261 env->DWMinorVersion = DW_MINOR_VERSION; |
5378 * Returns: | 5394 * Returns: |
5379 * DW_ERROR_NONE (0) on success. | 5395 * DW_ERROR_NONE (0) on success. |
5380 */ | 5396 */ |
5381 int API dw_init(int newthread, int argc, char *argv[]) | 5397 int API dw_init(int newthread, int argc, char *argv[]) |
5382 { | 5398 { |
5399 JNIEnv *env; | |
5400 | |
5401 if(!_dw_app_id[0]) | |
5402 { | |
5403 /* Generate an Application ID based on the PID if all else fails. */ | |
5404 snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid()); | |
5405 } | |
5406 | |
5407 if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) | |
5408 { | |
5409 // Construct a String | |
5410 jstring appid = env->NewStringUTF(_dw_app_id); | |
5411 jstring appname = env->NewStringUTF(_dw_app_name); | |
5412 // First get the class that contains the method you need to call | |
5413 jclass clazz = _dw_find_class(env, DW_CLASS_NAME); | |
5414 // Get the method that you want to call | |
5415 jmethodID dwInit = env->GetMethodID(clazz, "dwInit", | |
5416 "(Ljava/lang/String;Ljava/lang/String;)V"); | |
5417 // Call the method on the object | |
5418 env->CallVoidMethod(_dw_obj, dwInit, appid, appname); | |
5419 } | |
5383 return DW_ERROR_NONE; | 5420 return DW_ERROR_NONE; |
5384 } | 5421 } |
5385 | 5422 |
5386 /* | 5423 /* |
5387 * Cleanly terminates a DW session, should be signal handler safe. | 5424 * Cleanly terminates a DW session, should be signal handler safe. |
5482 * This will create a system notification that will show in the notifaction panel | 5519 * This will create a system notification that will show in the notifaction panel |
5483 * on supported systems, which may be clicked to perform another task. | 5520 * on supported systems, which may be clicked to perform another task. |
5484 */ | 5521 */ |
5485 HWND API dw_notification_new(const char *title, const char *imagepath, const char *description, ...) | 5522 HWND API dw_notification_new(const char *title, const char *imagepath, const char *description, ...) |
5486 { | 5523 { |
5524 JNIEnv *env; | |
5525 | |
5526 if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) | |
5527 { | |
5528 // Construct a String | |
5529 jstring appid = env->NewStringUTF(_dw_app_id); | |
5530 jstring ntitle = env->NewStringUTF(title); | |
5531 jstring ndesc = NULL; | |
5532 jstring image = NULL; | |
5533 | |
5534 if(description) | |
5535 { | |
5536 va_list args; | |
5537 char outbuf[1025] = {0}; | |
5538 | |
5539 va_start(args, description); | |
5540 vsnprintf(outbuf, 1024, description, args); | |
5541 va_end(args); | |
5542 | |
5543 ndesc = env->NewStringUTF(outbuf); | |
5544 } | |
5545 if(imagepath) | |
5546 image = env->NewStringUTF(imagepath); | |
5547 | |
5548 // First get the class that contains the method you need to call | |
5549 jclass clazz = _dw_find_class(env, DW_CLASS_NAME); | |
5550 // Get the method that you want to call | |
5551 jmethodID notificationNew = env->GetMethodID(clazz, "notificationNew", | |
5552 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroidx/core/app/NotificationCompat$Builder;"); | |
5553 // Call the method on the object | |
5554 jobject result = env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, notificationNew, ntitle, image, ndesc, appid)); | |
5555 return result; | |
5556 } | |
5487 return 0; | 5557 return 0; |
5488 } | 5558 } |
5489 | 5559 |
5490 /* | 5560 /* |
5491 * Sends a notification created by dw_notification_new() after attaching signal handler. | 5561 * Sends a notification created by dw_notification_new() after attaching signal handler. |
5494 * Returns: | 5564 * Returns: |
5495 * DW_ERROR_NONE on success, DW_ERROR_UNKNOWN on error or not supported. | 5565 * DW_ERROR_NONE on success, DW_ERROR_UNKNOWN on error or not supported. |
5496 */ | 5566 */ |
5497 int API dw_notification_send(HWND notification) | 5567 int API dw_notification_send(HWND notification) |
5498 { | 5568 { |
5569 JNIEnv *env; | |
5570 | |
5571 if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) | |
5572 { | |
5573 // First get the class that contains the method you need to call | |
5574 jclass clazz = _dw_find_class(env, DW_CLASS_NAME); | |
5575 // Get the method that you want to call | |
5576 jmethodID notificationNew = env->GetMethodID(clazz, "notificationSend", | |
5577 "(Landroidx/core/app/NotificationCompat$Builder;)V"); | |
5578 // Call the method on the object | |
5579 env->CallVoidMethod(_dw_obj, notificationNew, notification); | |
5580 return DW_ERROR_NONE; | |
5581 } | |
5499 return DW_ERROR_UNKNOWN; | 5582 return DW_ERROR_UNKNOWN; |
5500 } | 5583 } |
5501 | 5584 |
5502 /* | 5585 /* |
5503 * Converts a UTF-8 encoded string into a wide string. | 5586 * Converts a UTF-8 encoded string into a wide string. |