Java and Kotlin Plugin

A CordovaPlugin Subclass in Java and Kotlin

The native half extends CordovaPlugin and overrides execute(), which receives the action, a JSONArray of arguments and a CallbackContext for the answer; false means "no such action":

BookNestPlugin.java: execute() (package, imports and fields omitted)Java
  @Override
  public boolean execute(String action, JSONArray args, CallbackContext cb)
      throws JSONException {
    if (action.equals("info")) {
      cb.success(new JSONObject()
          .put("fontScale", cordova.getActivity().getResources().getConfiguration().fontScale)
          .put("sdkInt", Build.VERSION.SDK_INT)
          .put("canNotify", canNotify()));
      return true;
    }
    if (action.equals("remind")) {
      if (canNotify()) {
        post(args, cb);
      } else {
        waiting = cb;
        waitingArgs = args;
        cordova.requestPermission(this, 1, NOTIFY);  // the answer arrives below
      }
      return true;
    }
    return false;                                   // JavaScript receives "Invalid action"
  }

execute() runs on the WebView's JavaBridge thread (WebView and Bridge). Quick work such as info can answer at once; slow work belongs on cordova.getThreadPool(), and anything that touches views must go through cordova.getActivity().runOnUiThread(). From the console:

Calling the plugin, and an action it does not haveJavaScript
const info = await BookNest.info();
const unknown = await new Promise((resolve) =>
  cordova.exec(resolve, resolve, 'BookNest', 'fly', []));
({ info, unknown });
Output
{
  info: { fontScale: 1, sdkInt: 36, canNotify: false },
  unknown: 'Invalid action'
}

For Kotlin, turn on cordova-android 15's built-in Kotlin support (Kotlin 2.1.21) with <preference name="GradlePluginKotlinEnabled" value="true" /> in <platform name="android">. This info, built in a copy of BookNest, returned { fontScale: 1, sdkInt: 36, language: 'Kotlin' }:

BookNestPlugin.kt: the info action in Kotlin (package and imports omitted)Kotlin
class BookNestPlugin : CordovaPlugin() {
  override fun execute(action: String, args: JSONArray, cb: CallbackContext): Boolean {
    if (action != "info") return false
    cb.success(JSONObject()
      .put("fontScale", cordova.activity.resources.configuration.fontScale)
      .put("sdkInt", Build.VERSION.SDK_INT)
      .put("language", "Kotlin"))
    return true
  }
}