I need to get some properties of an html page which is loaded in a webview.
Something similar to what is here: stringByEvaluatingJavascriptFromString (iOS method, what is Android equivalent?)
So I have a JavaScriptInterface:
class MyJavaScriptInterface {
#android.webkit.JavascriptInterface
public void jsCallback(String jsResult) {
// your code...
Log.d("Debug", jsResult);
}
}
ant then here is the JS I use to get the string I need:
webView.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
webView.loadUrl("javascript:( "
+ "function () { "
+ "var htmltag = document.getElementsByTagName(\"html\");"
+ "var dataStr = htmltag[0].getAttribute(\"some-data-property-i-need\"); "
+ "console.log(window.HTMLOUT);"
+ "window.HTMLOUT.jsCallback(dataStr); } ) ()");
now in the console I see this traces:
06-02 01:14:06.409: V/CallNative fired:(26789): objc://domReady
06-02 01:14:06.464: I/Web Console(26789): undefined at null:1
06-02 01:14:06.480: E/Web Console(26789): Uncaught TypeError: Cannot call method 'jsCallback' of undefined at null:1
and I have no idea why "window.HTMLOUT" is undefined.
Please note that it was working at a point and then I modified a bit the JS part but I still cannot figure it out what could be the problem.
JS code can be executed after the whole page is loaded, have a try at this way:
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// Call JS code here
}
});
webView.loadDataWithBaseURL(null, "<html></html>", "text/html", "UTF-8", "");
If previous method does not work, please have a try at HTMLOUT.jsCallback(dataStr) instead of window.HTMLOUT.jsCallback(dataStr).
Related
I want to load to a about.html page inside asset folder by clicking a button in index.html inside android webview.
Here's the code:
Button:
About
Java:
WebView browser = (WebView) findViewById(webview);
browser.getSettings().setJavaScriptEnabled(true);
browser.setWebChromeClient(new WebChromeClient());
browser.loadUrl("file:///android_asset/www/index.html");
browser.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return false;
}
});
But the problem is when i click on button it doesn't load about.html but if I add a javascript function with below code it works.. but i want to use href.
Code:
<button onclick="about()">About</button>
<script>
function about() {
location.href = "about.html";
}
</script>
How do I solve it?
write an interface for TagHandler and in your fromHtml method check for the tag and handle it by loading the page
https://developer.android.com/reference/android/text/Html.html
try this code:
private void loadWebView(WebView webView,String htmlString)
{
try {
final String mimeType = "text/html";
final String encoding = "UTF-8";
WebViewClient yourWebClient = new WebViewClient()
{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
// This line we let me load only pages inside Webpage
if ( url.contains("") == true )
// Load new URL Don't override URL Link
return false;
// Return true to override url loading (In this case do nothing).
return true;
}
};
// Get Web view
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setSupportZoom(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.setWebViewClient(yourWebClient);
// Load URL
webView.loadDataWithBaseURL("", htmlString, mimeType, encoding, "");
} catch (Exception e) {
e.printStackTrace();
}
}
use it as:
loadWebView(browser, "file:///android_asset/www/index.html") //pass url
I need to load localStorage parameter to webView:
$.ajaxSetup({
data: {
token: localStorage.userToken
}
});
sendToApp = function(_key, _val) {
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", _key + ":##sendToApp##" + _val);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);iframe = null;
}
IsMobile = true;
$.when(
loadData.setup()
).then(function(data) {
Setup = data;
Struct = new App.Collection.Struct();
View = new App.View.Phone();
Zone = new App.Collection.Zone();
Zone.setAll();
Zone.findWhere({id:"0"}).set('path', 'Favourites')
Struct.startLoop();
});
My code looks like that:
public void setupWebView(String url, String token) {
webView.setWebChromeClient(new WebChromeClient());
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setJavaScriptEnabled( true );
webView.loadUrl(url);
webView.loadUrl("javascript:localStorage.setItem(\"userToken\",\"" + token + "\")");
}
What do I need to do to avoid this error:
I/chromium: [INFO:CONSOLE(1)] "Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.", source: (1)
My url format is "http://" + addressIp:port + "/m.php". I can access it from my internet PC browser.
Before firing any JavaScript you have to make sure your page is loaded and the window property is available, to do so you can make use of WebViewClient::onPageFinished method.
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
webView.loadUrl("javascript:localStorage.setItem(\"userToken\",\"" + token + "\")");
}
});
I'm having a problem with my code when running on a Android 4.4.2 KitKat (API 19) emulator...
When I emulate my project on a Android 4.3 (API 18) emulator, it works normally and creates the mathematical expressions with MathJax:
Image of emulator
But when I use a Android 4.4.2 emulator, the app don't work correctly:
Image of emulator
Here is the code of my project:
package com.testes.testesapp;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity implements View.OnClickListener {
private int exampleIndex = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
WebView webView = (WebView) findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
//webView.getSettings().setBuiltInZoomControls(true);
webView.loadDataWithBaseURL("http://test", "<script type='text/x-mathjax-config'>"
+ "MathJax.Hub.Config({ "
+ "showMathMenu: false, "
+ "jax: ['input/TeX','output/HTML-CSS'], " // output/SVG
+ "extensions: ['tex2jax.js','toMathML.js'], "
+ "TeX: { extensions: ['AMSmath.js','AMSsymbols.js',"
+ "'noErrors.js','noUndefined.js'] }, "
// + "'SVG' : { blacker: 30, "
// + "styles: { path: { 'shape-rendering': 'crispEdges' } } } "
+ "});</script>"
+ "<script type='text/javascript' "
+ "src='file:///android_asset/MathJax/MathJax.js'"
+ "></script>"
+ "<span id='math'></span>","text/html","utf-8","");
EditText edit = (EditText) findViewById(R.id.edit);
edit.setBackgroundColor(Color.LTGRAY);
edit.setTextColor(Color.BLACK);
edit.setText("");
Button btnShow = (Button) findViewById(R.id.btnShow);
btnShow.setOnClickListener(this);
Button btnClear = (Button) findViewById(R.id.btnClear);
btnClear.setOnClickListener(this);
Button btnExample = (Button) findViewById(R.id.btnExample);
btnExample.setOnClickListener(this);
}
private String doubleEscapeTeX(String s) {
String t="";
for (int i=0; i < s.length(); i++) {
if (s.charAt(i) == '\'') t += '\\';
if (s.charAt(i) != '\n') t += s.charAt(i);
if (s.charAt(i) == '\\') t += "\\";
}
return t;
}
private String getExample(int index) {
return getResources().getStringArray(R.array.tex_examples)[index];
}
public void onClick(View v) {
if (v == findViewById(R.id.btnShow)) {
WebView webView = (WebView) findViewById(R.id.webview);
EditText edit = (EditText) findViewById(R.id.edit);
webView.loadUrl("javascript:document.getElementById('math').innerHTML='\\\\["
+ doubleEscapeTeX(edit.getText().toString()) + "\\\\]';");
webView.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);");
}
else if (v == findViewById(R.id.btnClear)) {
WebView webView = (WebView) findViewById(R.id.webview);
EditText edit = (EditText) findViewById(R.id.edit);
edit.setText("");
webView.loadUrl("javascript:document.getElementById('math').innerHTML='';");
}
else if (v == findViewById(R.id.btnExample)) {
WebView webView = (WebView) findViewById(R.id.webview);
EditText edit = (EditText) findViewById(R.id.edit);
edit.setText(getExample(exampleIndex++));
if (exampleIndex > getResources().getStringArray(R.array.tex_examples).length - 1)
exampleIndex=0;
webView.loadUrl("javascript:document.getElementById('math').innerHTML='\\\\["
+ doubleEscapeTeX(edit.getText().toString()) + "\\\\]';");
webView.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);");
}
}
}
When I press the "Example" or the "Show" button, LogCat emits the errors:
I/chromium(1254): [INFO:CONSOLE(1)] "Uncaught TypeError: Cannot set property 'innerHTML' of null", source: http://test/ (1)
I/chromium(1254): [INFO:CONSOLE(1)] "Uncaught ReferenceError: MathJax is not defined", source: http://test/ (1)
I have no idea how to fix this problem, and would like somebody's help to solve this. Thanks.
I got this problem too.
Here is my solution:
change your base URL from "http://test" to "http://test/"
change this code webView.loadUrl(..) to webView.evaluateJavascript(..);. Especially for code where we want to load innerHTML. Don't forget to add anotation #TargetApi(Build.VERSION_CODES.KITKAT) because it's only for Android 4.4 and above
never put webView.loadWithBaseUrl(..) in the same process with webView.loadUrl(..). Because If webView.loadUrl(..) was loaded before webView.loadWithBaseUrl(..) finished, it will raise error as OP stated above.
For number 3, your codes is already conform with this (because in your codes, webView.loadUrl(..) execution was already separated with webView.loadWithBaseUrl(..) by using OnClick event. So, don't pay attention to it.
But if your apps need to load them at one event, consider to separate them by using this code:
`
private void initiateWebView(){
webViewEquationDisplay.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
loadUrlKitKat(equationSymbolFinal+equationToBeDisplayedFinal);
}
else{
webViewEquationDisplay.loadUrl("javascript:document.getElementById('math').innerHTML='<font color=\"yellow\">`"+equationToBeDisplayedFinal+"`</font>';");
}
webViewEquationDisplay.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);");
}
});
final String mathJaxOfflineUrl = "file:///android_asset/MathJax/MathJax.js";
webViewEquationDisplay.loadDataWithBaseURL("http://bar/", "<script type='text/x-mathjax-config'>"
+"MathJax.Hub.Config({ "
+"showMathMenu: false, "
+"jax: ['input/AsciiMath','output/HTML-CSS'], "
+"extensions: ['asciimath2jax.js'], "
+"AsciiMath: { fixphi: true, useMathMLspacing: true, displaystyle: false, decimalsign: \".\" }, "
+"});</script>"
+"<script type='text/javascript' "
+"src='"+mathJaxOfflineUrl+"'"
+"></script><span id='math'></span>","text/html","utf-8","");
}
#TargetApi(Build.VERSION_CODES.KITKAT)
private void loadUrlKitKat(String param){
webViewEquationDisplay.evaluateJavascript("javascript:document.getElementById('math').innerHTML='<font color=\"#97FD97\">`"+param+"`</font>';",null);
}
`
good luck
I had the same problem when I moved different javascript functions out of the main page to an separate .js file. For some reason, Android can't find externally-loaded JavaScript webview functions from Java - only the ones in the main page. Once I moved the function back from the JS file, it immediately started working.
Try making a "proxy" function like this directly inside the main HTML:
function proxy() {
call_some_other_function_from_JS_file();
}
This worked for me. I'm sure there must be a way to get find these functions, because I didn't have this problem on iOS. Someone please comment if you know a better way.
webview.evaluateJavascript("javascript:document.getElementById('math').innerHTML='"+doubleEscapeTeX(questn)+"';",null);
webview.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);");
This is the sollution for api 19 or above
I am calling a simple JS function to set values of some html contents, but its not working
Here is the JS function
function SetEdits(name,email,pic,date)
{
document.getElementById("myPic").src=pic;
document.getElementById("fullname").value=name;
document.getElementById("email").value=email;
}
and here is the code from android activity
edit.loadUrl("edit.html");
edit.loadUrl("javascript:SetEdits('"+name+"','"+email+"','"+picture+"','"+date+"')");
its not settings these fileds.. is there any problem with the synax where i am calling this function in native activity?
You're probably ending up evaluating the JavaScript before the "edit.html" page has loaded. Try this:
// I'm assuming the real path is something like file:///android_asset/edit.html
edit.loadUrl("edit.html");
edit.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
if (Uri.parse(url).getPath() == "edit.html") {
view.loadUrl("javascript:SetEdits('" + name+"','" + email + "','" +
picture + "','" + date + "')");
}
}
Have you enabled the javascript for the webview ?
You have to setup a javascript interface between your app and html.
Here is some details Webapp guid
I am trying to use JavaScript in an Android webview. I used following code. I did not get color changed or offset height of body.
webview.getSettings().setJavaScriptEnabled(true);
webview.addJavascriptInterface(new myJavaScriptInterface(webview), "jsInterface");
webview.loadUrl("file:///android_asset/sample/contents.html");
//webview.loadData("file:///android_asset/sample",convertStreamToString(inputStream), "text/html", "UTF-8");
webview.loadUrl("javascript:" +
"document.getElementsByTagName('p')[0].style.color='red';" +
"");
wbview.loadUrl("javascript:window.jsInterface.EchoText(document.body.offsetHeight);");
//webview.
}
class myJavaScriptInterface
{
WebView mywebview;
public myJavaScriptInterface(WebView webview)
{
this.mywebview=webview;
}
public void EchoText(String message)
{
Toast.makeText(mywebview.getContext(), message, Toast.LENGTH_SHORT).show();
}
}
What am I missing?
I think this is because your page is not loaded (still loading) when you are using webview.loadUrl("javascript:" + ...) statements.
Try the following...
webview.loadUrl("file:///android_asset/sample/contents.html");
webview.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView webview, String url) {
webview.loadUrl("javascript:" +
"document.getElementsByTagName('p')[0].style.color='red';");
wbview.loadUrl("javascript:" +
"window.jsInterface.EchoText(document.body.offsetHeight);");
}
});