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":
@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:
const info = await BookNest.info();
const unknown = await new Promise((resolve) =>
cordova.exec(resolve, resolve, 'BookNest', 'fly', []));
({ info, unknown });{
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' }:
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
}
}