使用PhoneGap的Andr​​oid的JavaScript调用 [英] Javascript calls from Android using PhoneGap

查看:197
本文介绍了使用PhoneGap的Andr​​oid的JavaScript调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经和应用程序构建与的PhoneGap ,我试图用 JavaScript来沟通从本地code。

I have and application built with PhoneGap, and I'm trying to communicate with Javascript from native code.

在我的 DroidGap 扩展类:

@Override
public void onCreate(Bundle savedInstanceState) {
    Logger.log("oncreate");
    super.onCreate(savedInstanceState);
    super.init();
    super.appView.getSettings().setJavaScriptEnabled(true);
    super.appView.getSettings().setSupportZoom(true);
    super.appView.getSettings().setBuiltInZoomControls(true);
    super.appView.getSettings().setDisplayZoomControls(false);
    jsinterface = new CommunicationInterface(this, appView);
    super.appView.addJavascriptInterface(jsinterface, "communicationinterface"); 
}

在javascriptinterface:

the javascriptinterface:

public class CommunicationInterface {
    private WebView mAppView;
    private DroidGap mGap;

    public CommunicationInterface(DroidGap gap, WebView view)  {
        mAppView = view;
        mGap = gap;
    }

    public String getTestString() {
        return "teststring";
    }

    public void parse(Object o) {
        Logger.log(o);
    }
}

Javacript 位于外部文件(创建具有该行的头一个HTML文件<脚本类型=文/ JavaScript的SRC =scripts.js>< / SCRIPT>

The Javacript is located in an external file (I create an HTML file which has this line in the header: <script type="text/javascript" src="scripts.js"></script>)

Scripts.js

function sendToInterface() {
    alert("alert");
    var map = new Object();
    (...)
    window.communicationinterface.parse(map); //communication js -> android seems to work.
}

我读其他职位,这是可能的PhoneGap和Android之间的沟通,但thusfar我没有成功。我还是设法创建一个警报,但是这与使用loadURL(JavaScript的:警报('报警');),但我也看到了,你不应该做T,因为这是 sendJavascript()是(,它会导致渗漏,重新加载页面等)。我试图通过 sendJavascript()的方法来拍了几个字符串,但无济于事:

I read in other posts that it's possible to communicate between PhoneGap and Android, but thusfar I've not had any success. I did manage to create an alert, but that was with loadUrl("javascript:alert('Alert');"), but I've also read that you shouldn't do because that's what sendJavascript() is for (and it causes leaks, reloads page, etc). I've tried to shoot a couple of Strings through the sendJavascript() method, but to no avail:

  • sendJavascript(JavaScript的:警报('报警');)
  • sendJavascript(JavaScript的:sendToInterface();)
  • sendJavascript(sendToInterface();)
  • sendJavascript(window.sendToInterface();)
  • sendJavascript("javascript:alert('Alert');")
  • sendJavascript("javascript:sendToInterface();")
  • sendJavascript("sendToInterface();")
  • sendJavascript("window.sendToInterface();")

如何从本地通信 - > PhoneGap的(或者有什么错什么,我已经有)? Thusfar其他职位和问题并没有帮助我解决这个特定的问题。

How to communicate from native -> PhoneGap (or what's wrong with what I already have)? Thusfar other posts and questions haven't helped me with this particular problem.

阅读:

  • http://www.jumpbyte.com/2012/phonegap-native -to-的JavaScript /
  • <一个href="http://stackoverflow.com/questions/15603395/phonegap-processmessage-failed-unable-to-send-javascript-function-cordova-2">Phonegap: &QUOT;而processMessage失败&QUOT;无法发送的JavaScript函数(科尔多瓦2.5.0)
  • <一个href="http://stackoverflow.com/questions/2727763/communication-between-android-java-and-phonegap-javascript">Communication Android的Java和Javascript的的PhoneGap?(虽然这是另外一个方向,但我想做两者)
  • 之间
  • <一个href="http://www.intelligrape.com/blog/2013/01/31/using-sendjavscript-to-inject-javascript-into-android-phonegap-application/" rel="nofollow">http://www.intelligrape.com/blog/2013/01/31/using-sendjavscript-to-inject-javascript-into-android-phonegap-application/
  • <一个href="http://stackoverflow.com/questions/8271536/phonegap-android-calling-javascript-from-native-causes-leakedwindow">Phonegap - Android的 - 从原生的原因调用javascript的leakedwindow
  • <一个href="http://stackoverflow.com/questions/11716167/how-to-call-javascript-function-from-android-using-phonegap-plugin">how使用来自Android的调用javascript函数的PhoneGap插件
  • http://www.jumpbyte.com/2012/phonegap-native-to-javascript/
  • Phonegap: "processMessage failed" unable to send javascript function (Cordova 2.5.0)
  • Communication between Android Java and Phonegap Javascript? (although this is the other direction, but I'm trying to do both)
  • http://www.intelligrape.com/blog/2013/01/31/using-sendjavscript-to-inject-javascript-into-android-phonegap-application/
  • Phonegap - Android - Calling javascript from native causes leakedwindow
  • how to call javascript function from android using phonegap plugin

修改

我写了一个工作项目:

Java的一部分

import org.apache.cordova.DroidGap;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.Bundle;
import android.util.Log;

public class App extends DroidGap {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    super.loadUrl("file:///sdcard/ds/index.html");
    System.out.println("loading from sdcard");
    Thread t = new Thread() {
      public void run() {
        try {
          for (int i = 0; i < 3; i++) {
            sleep(2000);
            sendValue("value " + i, "another vlaue " + i);
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
      };
    };
    t.start();
  }

  public void sendValue(String value1, String value2) {

    System.out.println("sendvalue in app");
    JSONObject data = new JSONObject();
    try {
      data.put("value1", value1);
      data.put("value2", value2);
    } catch (JSONException e) {
      Log.e("CommTest", e.getMessage());
    }
    String js = String.format("window.plugins.appcomm.updateValues('%s');",
        data.toString());
    this.sendJavascript(js);
  }
}

import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class AppComm extends Plugin{

  private static AppComm instance;

  public AppComm () {
    instance = this;
  }

  public static AppComm getInstance() {
    return instance;
  }

  @Override
  public PluginResult execute(String action, JSONArray args, String callbackId) {
    System.out.println("in execute from appcomm");


    return null;
  }

  public void sendValue(String value1, String value2) {
    System.out.println("sendvalue in appComm");
    JSONObject data = new JSONObject();
    try {
      data.put("value1", value1);
      data.put("value2", value2);
    } catch (JSONException e) {
      Log.e("CommTest", e.getMessage());
    }
    String js = String.format(
        "window.plugins.commtest.updateValues('%s');",
        data.toString());
    this.sendJavascript(js);
  }
}

RES / XML / plugins.xml

res/xml/plugins.xml

<plugins>
    <plugin name="App" value="org.apache.cordova.App"/>
    <plugin name="Geolocation" value="org.apache.cordova.GeoBroker"/>
    <plugin name="Device" value="org.apache.cordova.Device"/>
    <plugin name="Accelerometer" value="org.apache.cordova.AccelListener"/>
    <plugin name="Compass" value="org.apache.cordova.CompassListener"/>
    <plugin name="Media" value="org.apache.cordova.AudioHandler"/>
    <plugin name="Camera" value="org.apache.cordova.CameraLauncher"/>
    <plugin name="Contacts" value="org.apache.cordova.ContactManager"/>
    <plugin name="File" value="org.apache.cordova.FileUtils"/>
    <plugin name="NetworkStatus" value="org.apache.cordova.NetworkManager"/>
    <plugin name="Notification" value="org.apache.cordova.Notification"/>
    <plugin name="Storage" value="org.apache.cordova.Storage"/>
    <plugin name="Temperature" value="org.apache.cordova.TempListener"/>
    <plugin name="FileTransfer" value="org.apache.cordova.FileTransfer"/>
    <plugin name="Capture" value="org.apache.cordova.Capture"/>
    <plugin name="Battery" value="org.apache.cordova.BatteryListener"/>
    <plugin name="SplashScreen" value="org.apache.cordova.SplashScreen"/>

    <plugin name="AppComm" value="com.example.plugin.AppComm"/>
</plugins>

cordova.xml

cordova.xml

<?xml version="1.0" encoding="utf-8"?>
<cordova>
    <access origin=".*"/> <!-- allow local pages -->
    <log level="DEBUG"/>
    <preference name="classicRender" value="true" />
</cordova>

的index.html头

Index.html header

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0" />
    <title>
    </title>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.css" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
    </script>
    <script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js">
    </script>
    <script type="text/javascript" charset="utf-8" src="cordova.js"></script>   
    <script type="text/javascript" charset="utf-8">
    var AppComm=function(){};

    AppComm.prototype.updateValues=function(a){
    var map = new Object();
    map["X1"] = "hallo";
    map["X2"] = "hi";
    cordova.exec(null, null, null);
    };

    cordova.addConstructor(function(){cordova.addPlugin("appcomm",new AppComm)});
    </script>
</head>

其中一个问题是,JavaScript是在一个单独的文件(我认为这是一个问题)。如果不是过分的要求,我怎么能正确调用java回来,并用什么样的价值观?如何实现execute方法,以及如何称呼它(我真的不擅长的JQuery)?

One of the problems was that javascript was in a separate file (I think that was one of the problems). If it isn't to much to ask, how can I properly call java back, and with what values? How to implement the execute method and how to call it (I'm really bad at JQuery)?

推荐答案

首先,您使用的是插件子类。 插件已去precated,并已被替换 CordovaPlugin 。如果您使用的是旧版本的PhoneGap的,我会建议你升级。

Firstly, you are using a Plugin subclass. Plugin has been deprecated and has been replaced with CordovaPlugin. If you're using an old version of PhoneGap, I would recommend that you upgrade.

其次,你的exec调用是错误的。该文档的插件开发明确规定,你必须通过5个​​参数,而你传递3空。你怎么想到要如何处理?

Secondly, your exec call is wrong. The docs for plugin development clearly state that you have to pass 5 parameters, while you're passing 3 nulls. How do you expect that to be handled?

cordova.exec(function(winParam) {}, function(error) {}, "service",
             "action", ["firstArgument", "secondArgument", 42,
             false]);

在这里,服务动作和参数数组确定会在你的Java $ C $发生什么C。前两个决定将在JavaScript的发生在一定条件下是什么。因此,尽管你可以用空了前两个,你必须指定最后三个。

Here, the service, action and the array of parameters determine what will happen in your Java code. The first two determine what will happen in JavaScript under certain conditions. So, while you can use null for the first two, you have to specify the last three.

我有一个工作示例插件,与PhoneGap的2.3.0工程。请参见下面的code:

I have a working example plugin that works with PhoneGap 2.3.0. See the code below:

public class ExampleJSCommunicator extends CordovaPlugin {

    public boolean execute (final String action, final JSONArray args, CallbackContext callbackContext) throws JSONException {
        PluginResult.Status status = PluginResult.Status.OK;
        String result = "";

        cordova.getActivity ().runOnUiThread (new Runnable () {
            @Override
            public void run() {
                try {
                    String displayText = "";
                    if (action.equals ("buttonClicked")) {
                        displayText = args.getString(0) + " was clicked";
                    }

                    else if (action.equals ("animationRunning")) {
                        displayText = args.getBoolean(0) ? "Animation started running" : "Animation stopped running";
                    }

                    TextView label = (TextView) cordova.getActivity().findViewById (R.id.textView);
                    label.setText (displayText + " and the Activity knows it!");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });

        return true;
    }
}

随着code以上,你有你的Java端插件能够处理两个自定义行动 - buttonClicked animationRunning 。这些行动为我的目的,但你可以,否则他们的名字。

With the code above, you have your Java-side plugin capable of handling two custom "actions" - buttonClicked and animationRunning. These actions serve my purposes, but you could name them otherwise.

现在,你仍然需要注册你的插件,将让科尔多瓦知道。这是在 XML / config.xml中文件来完成。在插件,您必须添加以下内容:

Now, you still need to register your plugin, so that Cordova will know about it. This is done in the xml/config.xml file. Under plugins, you have to add the following:

<plugin name="ExampleJSCommunicator" value="com.example.phonegap.ExampleJSCommunicator"/>

然后你可以从JavaScript传递数据(或动作),如下所示。请注意,参数( which.id animationRunning 传递数组中的):

Then you can pass data (or "actions") from JavaScript as follows. Note that the parameters (which.id and animationRunning are passed in an array):

cordova.exec (null, null, "ExampleJSCommunicator", "buttonClicked", [which.id]);  // my first action
cordova.exec (null, null, "ExampleJSCommunicator", "animationRunning", [animationRunning]);  // my second action

这两个 EXEC 通话将触发的 ExampleJSCommunicator 类执行方法,并在相应的,如果得到处理块。不要紧,你叫EXEC,只要你申报你的JavaScript code后,包括cordova.js文件。我的JavaScript包含在一个单独的main.js文件,它工作得很好:

These two exec calls will trigger the execute method in the ExampleJSCommunicator class and will get handled in the respective if blocks. It doesn't matter where you call exec, as long as you declare your JavaScript code after you include the cordova.js file. My JavaScript is contained within a separate main.js file and it works just fine:

<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8" src="main.js"></script>

这篇关于使用PhoneGap的Andr​​oid的JavaScript调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆