WebView and Javascript Interface problems with SherlockActionBar - javascript

I have a problem: when I use webview with javascript interface to comunication between my activity and the html page, my actionbarsherlock stop working. And the problem is in this line:
myWebView.addJavascriptInterface(new JsObject(), "injectedObject");
the problems include List navigations and menu items with ActionView .
Basically if I comment the above code, everything works normally.
Some pictures to explain:
My Activity with sherlockactionbar and webview
My actionbar not working when when I'm calling the method addJavascriptInterface in my webview
My actionbar working when I remove the method addJavascriptInterface
How can I solve this problem???? Thanks.

Oh, I figured out my problem looking at this question
Basically I had a method accessed by javascript that disguised a view. So this occasioned UI errors.
Before:
class JsObject {
#JavascriptInterface
public void cancelProgress() {
progressbar.setVisibility(View.GONE);
}
}
After:
class JsObject {
#JavascriptInterface
public void cancelProgress() {
runOnUiThread(new Runnable(){
#Override
public void run(){
progressbar.setVisibility(View.GONE);
}
});
}
}

Related

Sound isn't played

I need to use a text to speech library. I decided to use https://responsivevoice.org/ . The integration is fairly easy, however, since my project uses GWT it is - obviously - not so straight forward.
Here is my java code that is a minimal proof of concept class:
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.ScriptInjector;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.*;
public class InverseVoiceTrainer extends SimplePanel implements ClickHandler {
Button playBtn;
public InverseVoiceTrainer() {
ScriptInjector.fromUrl("https://code.responsivevoice.org/responsivevoice.js").setCallback(
new Callback<Void, Exception>() {
#Override
public void onSuccess(Void result) {
GWT.log("ResponsiveVoiceJS loaded.");
}
#Override
public void onFailure(Exception reason) {
GWT.log("ResponsiveVoiceJS loading FAILED!");
}
}).inject();
playBtn = new Button("Play");
playBtn.addClickHandler(this);
this.add(playBtn);
}
#Override
public void onClick(ClickEvent event) {
GWT.log("Onclick pressed");
playWord("This is a test message...");
}
public static native void playWord(String s) /*-{
console.log("playWord - 1");
responsiveVoice.speak(s);
console.log("playWord - 2");
}-*/;
}
So, looking into the console log I can see the following:
ResponsiveVoice r1.5.3
SuperDevModeLogger.java:71 ResponsiveVoiceJS loaded.
SuperDevModeLogger.java:71 Onclick pressed
InverseVoiceTrainer.java:40 playWord - 1
InverseVoiceTrainer.java:42 playWord - 2
Which tells me that (a) ResponsiveVoice seems to have been correctly loaded and (b) the sound should have been played. However, I do not hear anything and my sound volume is hearable. So, what is going wrong here?
Well, this might be not the best answer, but it worked for me.
First, just link the responsivevoice.js in hosting html page:
<script type="text/javascript" language="javascript" src="https://code.responsivevoice.org/responsivevoice.js"></script>
Then remove the ScriptInjector part of your code.
The last change is to add $wnd in playWord() method:
$wnd.responsiveVoice.speak(s);
Tested. Worked.

How to call Javascript from #JavascriptInterface method in webView, Android?

Here is my HTML page codes:
<script>
function native_callback() {
alert("Test")
}
</script>
<button onclick='native.appVersion()'>appVersion</button>
As you can see, there is only one button, and when I click the button, it will call the #JavascriptInterface method appVersion(). What I want to do is to call the javascript function native_callback() in the appVersion() method. Unfortunately, I will catch a java exception.
And Here is part of my java source codes of WebView class:
... // some other codes that not related
getSettings().setJavaScriptEnabled(true);
addJavascriptInterface(new InJavaScriptLocalObj(), "native");
... // some other codes that not related
final class InJavaScriptLocalObj {
#JavascriptInterface
public void appVersion() {
Log.i("JsInterface","Called!")
loadUrl("javascript:native_callback()");
}
}
And, I can catch the exception from web page :
Uncaught Error: Java exception was raised during method invocation -- From line 6 of http://my web page url
Line 6 is <button onclick='native.appVersion()'>appVersion</button>.
BTW, the cods Log.i("JsInterface","Called!") has been called, I can see the log.
What should I do ?
Solution
Actually, it's must be called in another thread but same as your WebView object.
Here is my codes:
web_view.post(new Runnable() {
#Override
public void run() {
web_view.loadUrl("javascript:native_callback()");
}
});
How about using handler ?
I checked it works well in my project.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
loadUrl("javascript:native_callback()");
}
}, 0);

Android webview activity,how to get js return value?

js code like this:
function a(){return "hello";}
in android webview activity, how to call js function a() get the return value "hello" ?
webview.addJavaInterface? webview.loadUrl()? i can`t get it.
please tell me how to solve the problem.
My advice would be:
1- Define a Javascript interface
A plain Java class with some methods and attributes, use annotation to expose the method you desire to the webview JS scope
public class MyInterface {
private WebView webView;
//pass the reference to the webview in your constructor
public JavascriptCallback(WebView webView) {
this.webView = webView;
}
//expose this method to the JS scope using annotation
#JavascriptInterface
void sumNumbers(final String num1, final String num2, final String JScallbackFn) {
this.javascriptCallback(JScallbackFn, num1 + num2);
}
//run the callback into the JS scope
void javascriptCallback(final String callback, final String result) {
webView.post(new Runnable() {
#Override
public void run() { webView.load("javascript:"+callback+"("+result+")", null);
}
});
}
2- Inject the JavaScript interface in your webview
webview.addJavascriptInterface(new MyInterface(this.getActivity(), webview), "MyInterface");
3- Invoke the JS method (from within the webview)
MyInterface.sumNumbers(12, 34, showResult);
function showResult(res) {
document.getElementById('myDiv').innerHTML(res);
}
For more extensive explanation about how webviews works on Android check the official documentation http://developer.android.com/guide/webapps/webview.html

How to change EditText content with Javascript?

We have a button in HTML. When the user clicks it, the value of my specific EditText should change, but it doesn't.
Code:
class ActivityTest extends Activity {
TextView textView1;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
WebView webView = (WebView) findViewById(R.id.webView);
webView.loadUrl("file:///android_res/raw/htmlimages.html");
webView.addJavascriptInterface(new MyTest(), "Scripts");
webView.getSettings().setJavaScriptEnabled(true);
textView1 = (TextView) findViewById(R.id.textView1);
}
public class MyTest {
void setText(String string)
{
textView1.setText(string);
}
}
}
Assuming that your html part is correct one thing that you need to do is make ui calls on the main thread.
so your code:
void setText(String string)
{
textView1.setText(string);
}
should be
#JavascriptInterface
public void setText() {
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText("Testing text");
}
});
}
You can't change some native view with javaScript (any web based language), there is no api for JS.
You can't access to the views and less change his properties.
You can do everything on a webView if you are confident with web more than java.
Load your web and show there the label, then you can change everything with JS.
Edit: You can inject or call methods from JS with this API as Bob says.
Hope this helps.

How to call javascript method from android

Hi In my android phonegap app i need to call the javascript method from android code (DroidGap).I have tried the sample code.
Here is my code:
super.loadUrl("file:///android_asset/www/index.html");
super.loadUrl("javascript:onload()");
When i use super.loadUrl("javascript:alert('hai')"); i am getting this alert.But when i use the method "onload" i am getting the error.
Here is my error in logcat:
Uncaught TypeError: Property 'onload' of object [object DOMWindow] is not a function at null:1
Here is my script in index.html:
<script type="text/javascript">
function onload()
{
alert("hai");
}
</script>
I dont know where i am wrong.Please guide me.Thanks in Advance.
Try this one and add this line also
super.setWebChromeClient(new WebChromeClient());
super.loadUrl("file:///android_asset/www/index.html");
After this line call like this onPageFinished
webview.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
webview.loadUrl("javascript:(function() {alert("hai") }
);
}
});
Android can only call the javascript method if an html page is currently loaded in webView
first call
webview.loadUrl("Your html page url");
then call
webView.loadUrl("javascript:hello()");
Try to handle the alert function in the java file, like this :
mWebView.setWebChromeClient(new MyWebChromeClient());
final class MyWebChromeClient extends WebChromeClient {
#Override
public boolean onJsAlert(WebView view,String url,
String message,JsResult result) {
new AlertDialog.Builder(MainActivity.this).
setTitle("Alert").setMessage(message).setPositiveButton("OK",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
}
}).create().show();
result.confirm();
return super.onJsConfirm(view,url,message, result);
}
}
I had the same problem when I moved the target javascript function from the main page to an separate .js file. For some reason, the loadUrl() function can't find externally-loaded functions - only the ones in the main page. Once I moved the function back, it immediately started working.
Go figure.

Categories