3

I have created a cordova application. I am running an background service to perform some native task in the application. I need to trigger a java-script event once the background service complete its task. Is it possible to trigger js events from android?. Not able to find any solid answers for this. I need events because the application wound wait for the task in background service to complete. I want to event to notify the application that the task is complete. Is there any better way to implement this logic?.

1 Answer 1

3

Cordova itself doesn't expose its webview properties publicly for use by other Java classes, but you can do this with a minimal Cordova plugin which would allow your background service to access the Cordova webview in order to execute javascript in it from the Java layer. Then it's just a question of injecting the JS to trigger an event.

First you'd create a Cordova plugin to expose the necessary elements of Cordova to your background service:

public class MyPlugin extends CordovaPlugin{
    private static final String TAG = "MyPlugin";
    static MyPlugin instance = null;
    static CordovaWebView cordovaWebView;
    static CordovaInterface cordovaInterface;

    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
        super.initialize(cordova, webView);

        instance = this;
        cordovaWebView = webView;
        cordovaInterface = cordova;
    }

    @Override
    public void onDestroy() {
        instance = null;
    }

    private static void executeGlobalJavascript(final String jsString) {
        if (instance == null) {return;}
        instance.cordovaInterface.getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    instance.cordovaWebView.loadUrl("javascript:" + jsString);
                } catch (Exception e) {
                    Log.e(TAG, "Error executing javascript: "+ e.toString());
                }
            }
        });
    }

    public static void triggerJavascriptEvent(final String eventName){
        executeGlobalJavascript(String.format("document.dispatchEvent(new Event('%s'));", eventName));
    }
}

Then your background service can call the public method exposed by that plugin class:

public class MyService {
    public static void myMethod(){
        MyPlugin.triggerJavascriptEvent("myserviceevent");
    }
}

And finally, in your Cordova app's JS layer, you'd listen for your custom event:

document.addEventListener('myserviceevent', function(){
    console.log("myserviceevent received");
}, false);

I've created an example Cordova project which contains the minimal custom plugins required to achieve this which you can download here: http://ge.tt/8UeL6lu2

Once downloaded, unzip then:

cd cordova-test
cordova platform add android
cordova run android
Sign up to request clarification or add additional context in comments.

2 Comments

In this case you need to call this plugin from js. The initialize method will be called only when we call the plugin from js through exec method. So if i try to call it directly from service, the variables that are getting assigned inside initialize method will be null and the loadUrl method will not get called. Please correct me if i am wrong.
If you add <param name="onload" value="true" /> to your <feature> definition, the initialize() method will be called at app startup: see Plugin Initialization and Lifetime. My example project illustrates this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.