简体   繁体   English

从Cordova Java文件中调用JavaScript函数

[英]Call javascript function from cordova java file

This question seems like duplicate but I've tried with all the solutions in SO but nothing worked for me. 这个问题似乎很重复,但是我尝试了SO中的所有解决方案,但对我没有任何帮助。

My question is, I want to call the javascript function from cordova java file (Which is extended from CordovaPlugin ). 我的问题是,我想从cordova java文件(从CordovaPlugin扩展CordovaPlugin )调用javascript函数。 For this I've checked reference 1 , reference 2 , reference 3 and many more from online but nothing worked for me 为此,我已经从网上检查了参考书1参考书2参考书3以及更多内容,但对我没有用

My code 我的密码

Sample.js Sample.js

function sendVoice() {

try {
  ApiAIPlugin.requestVoice(
    {}, // empty for simple requests, some optional parameters can be here
    function (response) {
        // place your result processing here
        alert(JSON.stringify(response));
    },
    function (error) {
        // place your error processing here
        alert(error);
    });
  } catch (e) {
    alert(e);
  }
}

Sample.java Sample.java

WebView webView = new WebView(context);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
webView.loadUrl("javascript.sendVoice();");

I tried with simple alert in java file as below 我尝试在Java文件中使用简单的警报,如下所示

WebView webView = new WebView(MainActivity.this);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
webView.loadUrl("javascript:alert('hello')");

i'm able to watch the above alert , But I'm unable to access the javascript function from java file. 我能够看到上述alert ,但无法从Java文件访问javascript函数。 Any one have idea about this 任何人对此都有想法

Update 更新

VoiceBotPlugin.java VoiceBotPlugin.java

package VoiceBotPlugin;

public class VoiceBotPlugin extends CordovaPlugin {

Context context;
boolean recordAudio = false;


float newX, newY, dX, dY, screenHight, screenWidth;
ImageView img;
int lastAction;
WebView webView;
public String  sJava = "String from JAVA";

@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
    if (action.equals("coolMethod")) {
        String message = args.getString(0);
        this.coolMethod(message, callbackContext);

        this.webView.loadUrl("javascript:sendVoice();");
        //this.webView.evaluateJavascript("sendVoice();", null);

        context = this.cordova.getActivity();
        ((Activity) context).runOnUiThread(new Runnable() {
              @Override
              public void run() {
                createFlotingActionButton();
              }
        });

        return true;
    }
    return false;
}

private void coolMethod(String message, CallbackContext callbackContext) {
    if (message != null && message.length() > 0) {
        callbackContext.success(message);
    } else {
        callbackContext.error("Expected one non-empty string argument.");
    }
}


private void createFlotingActionButton(){

      FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
      params.topMargin = 0;
      params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;

      img = new ImageView(context);
      setImage(img, "icon_record");

      cordova.getActivity().addContentView(img, params);

      DisplayMetrics displaymetrics = new DisplayMetrics();
      ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
      screenHight = displaymetrics.heightPixels;
      screenWidth = displaymetrics.widthPixels;

      img.setOnTouchListener(new View.OnTouchListener() {
         @Override
         public boolean onTouch(View v, MotionEvent event) {


             switch (event.getActionMasked()) {
                 case MotionEvent.ACTION_DOWN:

                     dX = img.getX() - event.getRawX();
                     dY = img.getY() - event.getRawY();
                     lastAction = MotionEvent.ACTION_DOWN;
                     break;

                 case MotionEvent.ACTION_MOVE:

                     newX = event.getRawX() + dX;
                     newY = event.getRawY() + dY;

                     // check if the view out of screen
                     if ((newX <= 0 || newX >= screenWidth-img.getWidth()) || (newY <= 0 || newY >= screenHight-img.getHeight()))
                     {
                         lastAction = MotionEvent.ACTION_MOVE;
                         break;
                     }

                     img.setX(newX);
                     img.setY(newY);

                     lastAction = MotionEvent.ACTION_MOVE;

                     break;

                 case MotionEvent.ACTION_UP:
                     if (lastAction == MotionEvent.ACTION_DOWN) {
                        if (recordAudio) {
                            setImage(img, "icon_record");
                            recordAudio = false;
                        } else {
                            setImage(img, "icon_mute");
                            recordAudio = true;

                            //callJavaScriptFunction();

                        }
                    }
                     break;

                 default:
                     return false;
             }
             return true;

         }
      });

  }

  private void setImage(ImageView imageView, String iconName){
      Resources activityRes = cordova.getActivity().getResources();
      int backResId = activityRes.getIdentifier(iconName, "drawable", cordova.getActivity().getPackageName());
      Drawable backIcon = activityRes.getDrawable(backResId);
      if (Build.VERSION.SDK_INT >= 16)
        imageView.setBackground(null);
      else
        imageView.setBackgroundDrawable(null);

      imageView.setImageDrawable(backIcon);
  }

  private void callJavaScriptFunction(){
    WebView webView = new WebView(context);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.setWebChromeClient(new WebChromeClient());
    this.webView.loadUrl("javascript:sendVoice();");

    /*String js = String.format("window.sendVoice();", null);
    webView.sendJavascript(js);*/
  }

} }

You can try something like this - cordova and webView are implicitly defined by the CordovaPlugin class: 你可以尝试这样的事情- cordovawebView隐式由定义CordovaPlugin类:

public class MyPlugin extends CordovaPlugin {

    @Override
    public boolean execute(String action, JSONArray args,
                           CallbackContext callbackContext) throws JSONException {
        if(action.equals("foo")){
            executeGlobalJavascript("alert('hello')");
        }
        return true;
    }                       

    private void executeGlobalJavascript(final String jsString){
        cordova.getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                webView.loadUrl("javascript:" + jsString);
            }
        });
    }
}

For your example I think the best option is to use a callback: 对于您的示例,我认为最好的选择是使用回调:

So in your java you should use 因此,在您的Java中,您应该使用

PluginResult.Status status = PluginResult.Status.OK;
callbackContext.sendPluginResult(new PluginResult(status, ""));

And in your javascript you call the plugin like cordova.exec(sendVoice, null, "VoiceBotPlugin", "coolMethod", []); 然后在您的JavaScript中调用类似于cordova.exec(sendVoice, null, "VoiceBotPlugin", "coolMethod", []);的插件cordova.exec(sendVoice, null, "VoiceBotPlugin", "coolMethod", []); So when sendPluginResult is called it will execute sendVoice. 因此,当sendPluginResult时,它将执行sendVoice。

OLD: You are creating a new WebView , so it doesn't have access to your Cordova WebView , which is the one loading your javascript files. 老:您正在创建一个新的WebView ,因此它无权访问Cordova WebView ,后者是一个加载javascript文件的WebView

If your class is a subclass of CordovaPlugin , you should be able to access the Cordova WebView with the webView variable. 如果您的类是CordovaPlugin的子类, CordovaPlugin应该能够使用webView变量访问Cordova WebView

So to call sendVoice() you should use webView.loadUrl("javascript:sendVoice();"); 因此,要调用sendVoice()您应该使用webView.loadUrl("javascript:sendVoice();"); (note that you had javascript. and not javascript: in your example) (请注意,在您的示例中,您使用的是javascript.而不是javascript:

Also, sendVoice() should be a global function or it won't be able to find it. 另外, sendVoice()应该是全局函数,否则将无法找到它。

If you are targetting Android 4.4 or newer you can use evaluateJavascript instead of `loadUrl`` 如果您的目标是Android 4.4或更高版本,则可以使用evaluateJavascript Javascript而不是`loadUrl``

Something like webView.getEngine().evaluateJavascript("sendVoice();", null); 诸如webView.getEngine().evaluateJavascript("sendVoice();", null);

Both of them should be run inside runOnUiThread as on DaveAlden answer. 他们都应该内部运行runOnUiThread作为DaveAlden答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM