从cordova java文件调用javascript函数

Bah*_*ahu 0 javascript java android cordova

这个问题似乎是重复的,但我已经尝试了 SO 中的所有解决方案,但没有任何效果对我有用。

我的问题是,我想从cordova java 文件(从 扩展而来CordovaPlugin)调用javascript 函数。为此,我从网上检查了参考文献 1参考文献 2参考文献 3以及更多内容,但没有任何效果对我有用

我的代码

示例.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);
  }
}
Run Code Online (Sandbox Code Playgroud)

示例.java

WebView webView = new WebView(context);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
webView.loadUrl("javascript.sendVoice();");
Run Code Online (Sandbox Code Playgroud)

我尝试在 java 文件中使用简单的警报,如下所示

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

我可以观看上面的内容alert,但是我无法从 java 文件访问 javascript 函数。任何人都对此有想法

更新

语音机器人插件

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);*/
  }
Run Code Online (Sandbox Code Playgroud)

}

Dav*_*den 5

你可以尝试这样的事情 -cordova并且webViewCordovaPlugin类隐式定义:

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);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 问题是您已经在插件的 JS 组件中定义了 `sendVoice()`。Cordova 将包装它,这样 `sendVoice()` 将成为一个私有函数而不是全局函数。要使其成为全局对象,您需要将其显式分配给 window 对象:`window.sendVoice = function(){` (2认同)