How to run cordova plugin in Android background service?

后端 未结 3 840
礼貌的吻别
礼貌的吻别 2020-12-02 09:38

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 wi

相关标签:
3条回答
  • 2020-12-02 10:08

    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.

    0 讨论(0)
  • 2020-12-02 10:10

    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.

    0 讨论(0)
  • 2020-12-02 10:16

    To work with Cordova plugins in WebView as background service, i've created class that implements CordovaInterface. Here is an example

     private class CordovaBackground extends Activity implements CordovaInterface {
        private ArrayList pluginEntries = new ArrayList();
        private CordovaPreferences preferences;
        private Context context;
        private Whitelist internalWhitelist;
        private Whitelist externalWhitelist;
        private CordovaWebViewBackground webView;
        protected LinearLayout root;
        private WindowManager serviceWindowManager;
        private final ExecutorService threadPool = Executors.newCachedThreadPool();
    
        public CordovaBackground(Context context, WindowManager windowManager) {
            attachBaseContext(context);
            this.context = context;
            this.serviceWindowManager = windowManager;
        }
    
        private void loadConfig() {
            ConfigXmlParser parser = new ConfigXmlParser();
            parser.parse(this);
            preferences = parser.getPreferences();
            internalWhitelist = parser.getInternalWhitelist();
            externalWhitelist = parser.getExternalWhitelist();;
            ArrayList<PluginEntry> allPluginEntries = parser.getPluginEntries();
            String[] backgroundPluginNames = {"File"};//not all plugins you need in service, here is the list of them
            ArrayList<String> backgroundPlugins = new ArrayList<String>(
                Arrays.asList(backgroundPluginNames));
            for (PluginEntry pluginEntry : allPluginEntries) {
                if (backgroundPlugins.contains(pluginEntry.service)) {
                    pluginEntries.add(pluginEntry);
                }
            }
        }
    
        public void loadUrl(String url) {
            init();
            webView.loadUrl(url);
        }
    
        public void init() {
            loadConfig();
            webView = new CordovaWebViewBackground(context);
            if (webView.pluginManager == null) {
                CordovaWebViewClient webClient = webView.makeWebViewClient(this);
                CordovaChromeClientBackground webChromeClient = webView.makeWebChromeClient(this);
                webView.init(this, webClient, webChromeClient,
                        pluginEntries, internalWhitelist, externalWhitelist, preferences);
            }
        }
    
        public WindowManager getWindowManager() {
            return serviceWindowManager;
        }
    
        @Override
        public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
        }
    
        @Override
        public void setActivityResultCallback(CordovaPlugin plugin) {
        }
    
        @Override
        public Activity getActivity() {
            return this;
        }
    
        @Override
        public Object onMessage(String id, Object data) {
            return null;
        }
    
        @Override
        public ExecutorService getThreadPool() {
            return threadPool;
        }
    
        @Override
        public Intent registerReceiver(android.content.BroadcastReceiver receiver, android.content.IntentFilter filter) {
            return  getIntent();
        }
    
        @Override
        public String getPackageName() {
            return context.getPackageName();
        }
    
    }
    

    To prevent errors while cordova initializing, i've overrode onJsAlert method. If you have a time, you may have found better way.

     private class CordovaWebViewBackground extends CordovaWebView {
    
        public CordovaWebViewBackground(Context context) {
            super(context);
        }
    
        public CordovaChromeClientBackground makeWebChromeClient(CordovaInterface cordova) {
            return new CordovaChromeClientBackground(cordova, this);
        }
    
    }
    
    private class CordovaChromeClientBackground extends CordovaChromeClient {
    
        public CordovaChromeClientBackground(CordovaInterface ctx, CordovaWebView app) {
            super(ctx, app);
        }
    
        public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
            //super.onJsAlert(view, url, message, result);
            return true;
        }
    
    }
    

    How to use:

    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    CordovaBackground cordovaBackground = new CordovaBackground(this, wm);
    cordovaBackground.setIntent(intent);
    String url = "file:///android_asset/www/test.html";
    cordovaBackground.loadUrl(url);
    
    0 讨论(0)
提交回复
热议问题