2014-07-05 13 views
21

Sto lavorando all'applicazione mobile sviluppata su cordova. Voglio implementare un servizio in background che funziona come una connessione open socket sincronizzando il database locale con quello remoto e notificando gli utenti su nuovi push remoti, ecc. Il punto è che ho implementato questo codice in javascript ma voglio eseguirlo in background.Come eseguire il plug-in Cordova nel servizio in background Android?

Ho cercato internet per un plug-in del servizio di sfondo cordova.

Ho letto alcune tematiche circa servizio in background in Android questi sono quelli utili che ho trovato:

Così ho iniziato a scrivere Cordova plugin (principalmente su Android) per eseguire il ja codice vascript in background. Ho creato una webview dal servizio in background per eseguire il javascript da esso. Funziona bene quando eseguo il javascript normale, ma quando si tratta di plug-in cordova js non riesce ad esempio il dispositivo device.uuidnull.

Questo è il codice di servizio Java:

 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); 

    } 

Aggiornamento Non v'è alcun errore nel logcat. Così ho provato a scrivere l'oggetto dispositivo sullo schermo e questo è quello che ottengo:

document.write(JSON.stringify(window.device)) 

E questo è il risultato:

{ available : false, 
    plaform : null , 
    version : null , 
    uuid : null , 
    cordova : null , 
    model : null 
    } 

Ho provato a sostituire lo standard webView con cordovaWebView Ma lo stesso risultato è dato.

 //WebView wv = new WebView(this); Commented out 
     CordovaWebView wv = new CordovaWebView(this); 

Qualsiasi aiuto su questo problema?

+0

utile questo aiuto: http://stackoverflow.com/questions/21505369/phonegap-keep-running-on-android-after-onpause/21565628#21565628 – kirchberger

+0

Nel mio caso il javascript è attivo e continua a funzionare ma il problema è nell'esecuzione di ** cordova plugin js ** in background. – mehsen

+0

puoi pubblicare un errore o un registro – kirchberger

risposta

2

WebViews non può eseguire javascript da un servizio in background.

Si consiglia di utilizzare invece il codice nativo.Ma se è necessario utilizzare il javascript, vorrei provare questa libreria

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(); 
    } 

primo carico al contenuto del vostro scritto in una stringa e quindi eseguire engine.eval() metodo.

Esempio (Run "test.js" da attività):

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(); 
    } 

NOTA! La funzione eval si aspetta solo una funzione javascript da eseguire alla volta e restituisce il valore di questa funzione.

+0

Sto usando una webview instatiated nel servizio per eseguire il mio js e funziona, ma fallisce quando si usa javascript di plugin cordova – mehsen

+0

Qualche idea sul problema? – mehsen

+0

@mehsen non è possibile utilizzare i plugin Cordova senza inizializzazione. Quando il motore Cordova si inizializza, passa attraverso un processo elaborato per impostare i plug-in. Dovresti ripetere l'intero processo nel servizio in background. –

4

È necessario utilizzare Cordova WebView incorporato, non una WebView standard. Una WebView standard non è impostata per gestire i plugin Cordova e le informazioni sul dispositivo sono un plug-in.

Vedere Cordova docs on embedding webviews.

+0

Lo stesso risultato è dato che modificherò la mia domanda per vedere come uso cordovaWebView – mehsen

+0

Hai seguito tutti i passaggi nei documenti? Hai impostato un Threadpool per l'esecuzione dei plug-in? –

+0

Da quello che hai scritto nella tua risposta sembra che tu usi solo la classe CordovaWebView, ma nei documenti Cordova (link nella mia risposta) è chiaro che devono essere fatti ulteriori passi per configurare CordovaWebView. Sarà questa configurazione ad agganciare i plugin (ad esempio il plug-in della periferica che al momento non funziona). –

0

Per lavorare con i plugin Cordova in WebView come servizio in background, ho creato la classe che implementa CordovaInterface. Ecco un esempio

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(); 
    } 

} 

Per evitare errori durante l'inizializzazione Cordova, ho overrode onJsAlert metodo. Se hai un tempo, potresti aver trovato il modo migliore.

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; 
    } 

} 

Come usare:

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); 
Problemi correlati