I am working on mobile application developed on cordova . I want to implement a background service that do some work like open socket connection syncronise local database with remote one and notify the users on new remote pushes etc . The point is I have this code implemented in javascript but I want execute it i background.
I searched internet for a cordova background service plugin.
katzer/cordova-plugin-background-mode
jocull/phonegap-backgroundjs
red-folder
The best one I think is red-folder but it is just for android and it does not let me to write javascript to be executed in background. but just exchange json between java and javascript.
I have read some topics about background service in android these are useful ones I found:
So I started writing cordova plugin (primarily on android) to execute the javascript code in background. I created a webview from the background service to execute the javascript from it. This works fine when I execute normal javascript but when it comes to cordova plugins js it fails for example the device device.uuid
gives null
.
This is the java service code:
public void onStart(Intent intent, int startId) { Toast.makeText(this, "My Happy Service Started", Toast.LENGTH_LONG).show(); createBackGroundView(); super.onStart(intent,startId); } public void createBackGroundView(){ WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); LayoutParams params = new WindowManager.LayoutParams( android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT ); params.gravity = Gravity.TOP | Gravity.LEFT; params.x = 0; params.y = 0; params.width = 200; params.height = 200; LinearLayout view = new LinearLayout(this); view.setLayoutParams(new RelativeLayout.LayoutParams( android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.MATCH_PARENT )); WebView wv = new WebView(this); wv.setLayoutParams(new LinearLayout.LayoutParams( android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.MATCH_PARENT )); view.addView(wv); wv.getSettings().setJavaScriptEnabled(true); wv.setWebChromeClient(new WebChromeClient()); wv.loadUrl("file:///android_asset/www/background.html"); wv.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(final WebView view, int errorCode, String description, final String failingUrl) { Log.d("Error","loading web view"); super.onReceivedError(view, errorCode, description, failingUrl); } }); windowManager.addView(view, params); }
Update There is no error in the logcat. So I tried to write the device object on the screen and thats what I get :
document.write(JSON.stringify(window.device))
And this is the result :
{ available : false, plaform : null , version : null , uuid : null , cordova : null , model : null }
I tried to replace the standard webView
with cordovaWebView
But the same result is given.
//WebView wv = new WebView(this); Commented out CordovaWebView wv = new CordovaWebView(this);
Any help about this problem ?
You should use an embedded Cordova WebView, not a standard WebView. A standard WebView is not set up to handle Cordova plugins, and the device info is a plugin.
See the Cordova docs on embedding webviews.
WebViews can not execute javascript from a background service.
I would recommend using native code instead. But if you must use javascript, i would try this library
https://code.google.com/p/jav8/
ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("jav8"); try { engine.eval("print('Hello, world!')"); } catch (ScriptException ex) { ex.printStackTrace(); }
First load the contens of your script into a string and then run engine.eval()
method.
Example (Run "test.js" from assets):
AssetManager am = context.getAssets(); InputStream is = am.open("test.js"); BufferedReader r = new BufferedReader(new InputStreamReader(is)); StringBuilder total = new StringBuilder(); String line; while ((line = r.readLine()) != null) { total.append(line); } ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("jav8"); try { engine.eval(total.toString()); } catch (ScriptException ex) { ex.printStackTrace(); }
Notice! The eval
function expects only a javascript function to be executed at a time and returns the value of this function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With