Reputation: 1596
This question seems like duplicate but I've tried with all the solutions in SO but nothing worked for me.
My question is, I want to call the javascript function from cordova java file (Which is extended from CordovaPlugin
). For this I've checked reference 1, reference 2, reference 3 and many more from online but nothing worked for me
My code
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
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
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. Any one have idea about this
Update
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);*/
}
}
Upvotes: 1
Views: 3372
Reputation: 53351
For your example I think the best option is to use a callback:
So in your java you should use
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", []);
So when sendPluginResult
is called it will execute 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.
If your class is a subclass of CordovaPlugin
, you should be able to access the Cordova WebView
with the webView
variable.
So to call sendVoice()
you should use webView.loadUrl("javascript:sendVoice();");
(note that you had javascript.
and not javascript:
in your example)
Also, sendVoice()
should be a global function or it won't be able to find it.
If you are targetting Android 4.4 or newer you can use evaluateJavascript
instead of `loadUrl``
Something like webView.getEngine().evaluateJavascript("sendVoice();", null);
Both of them should be run inside runOnUiThread
as on DaveAlden answer.
Upvotes: 1
Reputation: 30366
You can try something like this - cordova
and webView
are implicitly defined by the CordovaPlugin
class:
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);
}
});
}
}
Upvotes: 6