# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1679877617 0 # Node ID e6fb2558e29e79b48d6fec5717c4c9e714a5de56 # Parent 0058ab32e1bd663a0435e7635b6627412700904c Android: Support for dw_html_javascript_add() and DW_SIGNAL_HTML_MESSAGE. Have to bump Android minimum API version to 26 (Oreo) for this to work. Not completely functional but I need change locations, it builds. diff -r 0058ab32e1bd -r e6fb2558e29e android/DWindows.kt --- a/android/DWindows.kt Sun Mar 26 22:10:10 2023 +0000 +++ b/android/DWindows.kt Mon Mar 27 00:40:17 2023 +0000 @@ -40,11 +40,13 @@ import android.view.* import android.view.View.OnTouchListener import android.view.inputmethod.EditorInfo +import android.webkit.JavascriptInterface import android.webkit.WebView import android.webkit.WebViewClient import android.widget.* import android.widget.AdapterView.OnItemClickListener import android.widget.SeekBar.OnSeekBarChangeListener +import androidx.annotation.RequiresApi import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.AppCompatEditText @@ -1495,6 +1497,7 @@ const val COLUMN_CLICK = 17 const val HTML_RESULT = 18 const val HTML_CHANGED = 19 + const val HTML_MESSAGE = 20 } val DWImageExts = arrayOf("", ".png", ".webp", ".jpg", ".jpeg", ".gif") @@ -1524,6 +1527,8 @@ } private class DWWebViewClient : WebViewClient() { + val HTMLAdds = mutableListOf() + //Implement shouldOverrideUrlLoading// @Deprecated("Deprecated in Java") override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { @@ -1537,6 +1542,9 @@ } override fun onPageFinished(view: WebView, url: String) { + // Inject the functions on the page on complete + HTMLAdds.forEach { e -> view.loadUrl("javascript:function $e(body) { DWindows.postMessage($e, body) }") } + // Handle the DW_HTML_CHANGE_COMPLETE event eventHandlerHTMLChanged(view, DWEvent.HTML_CHANGED, url, 4) } @@ -1544,6 +1552,17 @@ external fun eventHandlerHTMLChanged(obj1: View, message: Int, URI: String, status: Int) } +class DWWebViewInterface internal constructor(var view: View) { + /* Show a toast from the web page */ + @JavascriptInterface + fun postMessage(name: String?, body: String?) { + // Handle the DW_HTML_CHANGE_COMPLETE event + eventHandlerHTMLMessage(view, DWEvent.HTML_CHANGED, name, body) + } + + external fun eventHandlerHTMLMessage(obj1: View, message: Int, hmltName: String?, htmlBody: String?) +} + class DWPrintDocumentAdapter : PrintDocumentAdapter() { var context: Context? = null @@ -4740,6 +4759,7 @@ // Configure a few settings to make it behave as we expect html!!.webViewClient = DWWebViewClient() html!!.settings.javaScriptEnabled = true + html!!.addJavascriptInterface(DWWebViewInterface(html!!), "DWindows"); } return html } @@ -4769,6 +4789,14 @@ } } + fun htmlJavascriptAdd(html: WebView, name: String) + { + waitOnUiThread { + val client = html.webViewClient as DWWebViewClient + client.HTMLAdds += name + } + } + fun htmlAction(html: WebView, action: Int) { waitOnUiThread { diff -r 0058ab32e1bd -r e6fb2558e29e android/dw.cpp --- a/android/dw.cpp Sun Mar 26 22:10:10 2023 +0000 +++ b/android/dw.cpp Mon Mar 27 00:40:17 2023 +0000 @@ -5,7 +5,7 @@ * (C) 2011-2023 Brian Smith * (C) 2011-2022 Mark Hessling * - * Requires Android API 23 (Marshmallow) or higher. + * Requires Android API 26 (Oreo) or higher. * */ @@ -251,9 +251,7 @@ } DWSignalList; /* List of signals */ -#define SIGNALMAX 19 - -static DWSignalList DWSignalTranslate[SIGNALMAX] = { +static DWSignalList DWSignalTranslate[] = { { _DW_EVENT_CONFIGURE, DW_SIGNAL_CONFIGURE }, { _DW_EVENT_KEY_PRESS, DW_SIGNAL_KEY_PRESS }, { _DW_EVENT_BUTTON_PRESS, DW_SIGNAL_BUTTON_PRESS }, @@ -272,7 +270,9 @@ { _DW_EVENT_TREE_EXPAND, DW_SIGNAL_TREE_EXPAND }, { _DW_EVENT_COLUMN_CLICK, DW_SIGNAL_COLUMN_CLICK }, { _DW_EVENT_HTML_RESULT, DW_SIGNAL_HTML_RESULT }, - { _DW_EVENT_HTML_CHANGED, DW_SIGNAL_HTML_CHANGED } + { _DW_EVENT_HTML_CHANGED, DW_SIGNAL_HTML_CHANGED }, + { _DW_EVENT_HTML_MESSAGE, DW_SIGNAL_HTML_MESSAGE }, + { 0, "" } }; #define _DW_EVENT_PARAM_SIZE 10 @@ -475,6 +475,20 @@ free(uri); break; } + /* HTML message event */ + case _DW_EVENT_HTML_MESSAGE: + { + int (* API htmlmessagefunc)(HWND, char *, char *, void *) = (int (* API)(HWND, char *, char *, void *))handler->signalfunction; + char *name = (char *)params[1]; + char *body = (char *)params[2]; + + retval = htmlmessagefunc(handler->window, name, body, handler->data); + if(name) + free(name); + if(body) + free(body); + break; + } } } return retval; @@ -666,6 +680,25 @@ env->ReleaseStringUTFChars(URI, uri); } +JNIEXPORT void JNICALL +Java_org_dbsoft_dwindows_DWWebViewInterface_eventHandlerHTMLMessage(JNIEnv *env, jobject thiz, + jobject obj1, jint message, + jstring htmlName, jstring htmlBody) { + const char *name = env->GetStringUTFChars(htmlName, nullptr); + const char *body = env->GetStringUTFChars(htmlBody, nullptr); + void *params[_DW_EVENT_PARAM_SIZE] = { nullptr, DW_POINTER(name ? strdup(name) : nullptr), + DW_POINTER(body ? strdup(body) : nullptr), + nullptr, nullptr, nullptr, nullptr, nullptr, + DW_INT_TO_POINTER(message), nullptr }; + + _dw_event_handler(obj1, params); + if(name) + env->ReleaseStringUTFChars(htmlName, name); + if(body) + env->ReleaseStringUTFChars(htmlBody, body); +} + + typedef struct _dwprint { int (*drawfunc)(HPRINT, HPIXMAP, int, void *); @@ -885,12 +918,13 @@ /* Finds the message number for a given signal name */ ULONG _dw_findsigmessage(const char *signame) { - int z; - - for(z=0;zNewStringUTF(name); + // First get the class that contains the method you need to call + jclass clazz = _dw_find_class(env, DW_CLASS_NAME); + // Get the method that you want to call + jmethodID htmlJavascriptAdd = env->GetMethodID(clazz, "htmlJavascriptAdd", + "(Landroid/webkit/WebView;Ljava/lang/String;)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, htmlJavascriptAdd, handle, jstr); + if(!_dw_jni_check_exception(env)) + retval = DW_ERROR_NONE; + env->DeleteLocalRef(jstr); + } + return retval; +} + +/* * Create a new HTML window (widget) to be packed. * Parameters: * id: An ID to be used with dw_window_from_id() or 0L. @@ -8222,4 +8288,4 @@ #ifdef __cplusplus } -#endif \ No newline at end of file +#endif