Passing value from activity to Android webview for Javascript method - javascript

I'm trying to pass an array from my activity to javascript method in html file located in Assets dir.
I'm using JavascriptInterface passing my int array like JSONArray:
public class JavaScriptInterface {
Context mContext;
JavaScriptInterface(Context c) {
mContext = c;
}
#JavascriptInterface
public JSONArray getValues() {
String values = "[100,133,'',120,122,132,133]";
JSONArray jsonarr = null;
try {
jsonarr = new JSONArray(values);
}
catch(JSONException e) {
e.printStackTrace();
}
return jsonarr;
}
}
In javascript method, I take the values thus:
var data = JSON.parse(js.getValues());
Now, I'm testing my project on different devices and AVD:
the code works fine on Samsung Note 2 (JB 4.2.1) and on AVD with target Google APIs (API level 8) while on Asus Nexus 7 (JB 4.2.2) and others AVD with JB 4.2 the code stops working returns an Web Console error:
03-25 16:35:12.809: E/Web Console(11352): Uncaught SyntaxError:
Unexpected token o at file:///android_asset/data/test.html:1
I need these values for represent a chart using a Javascript library.
In addition, I modified the file proguard-project.txt denying the javascript code obfuscation:
keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}
-keep public class com.XXX.XXX.DataReportActivity$JavaScriptInterface
-keep public class * implements com.XXX.XXX.DataReportActivity$JavaScriptInterface
-keep classmembers class com.XXX.XXX.DataReportActivity$JavaScriptInterface {
<fields>;
<methods>;
}
-keepattributes JavascriptInterface
does anyone have any idea about solve it?
please, any help is welcome!

Change your Javascript Interface to return a String. JSON.parse is expecting a string, not a JSON object.
#JavascriptInterface
public String getValues() {
String values = "[100,133,'',120,122,132,133]";
return values;
}
The values string might need to be in quotes for the javascript function to be able to parse it too. In other words:
return "'" + values + "'";

Related

JavaScript removes // from URL

URL example = new URL(example.getExampleUrl());
exampleString += "example";
And I have problem with the url that removes // from link. So if I have http://www.google.pl, I get http: www.google.pl instead. I tried with a string, but then I have the same problem. Could anyone tell me how to make this string or url look like a regular link?
its look fine at java http://www.google.pl but at page it is without // so its look http: www.google.pl calendar etc
String test = "http://www.google.pl";
test
Answer to this is that there was a problem with " ' in java, i had to use it like that
onClick='MyWindow=window.open("+ example +")'
String example= "\"" + google.getUrl()+ "\",\""+google.getNameDisplay()+"\",\"width=600,height=600\"";
The toString() method of URL should return just what you want. Try this snippet:
import java.net.*;
import java.io.*;
class Main {
public static void main(String[] args) throws MalformedURLException {
URL example = new URL("http://mostmedia.com");
System.out.println(example.toString());
assert "http://mostmedia.com".equals(example.toString());
}
}
You can run it on repl.it: https://repl.it/CEVw/1

Server-side rendering of Java, ReactJs code on a web browser

What do I need to do to render this on browser? The code below currently works and renders on Eclipse Console. I need to use this code with a server like Tomcat and display it on browser with localhost. Please advice.
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.FileReader;
public class Test {
private ScriptEngine se;
// Constructor, sets up React and the Component
public Test() throws Throwable {
ScriptEngineManager sem = new ScriptEngineManager();
se = sem.getEngineByName("nashorn");
// React depends on the "global" variable
se.eval("var global = this");
// eval react.js
se.eval(new FileReader("../react-0.14.7/build/react.js"));
// This would also be an external JS file
String component =
"var MyComponent = React.createClass({" +
" render: function() {" +
" return React.DOM.div(null, this.props.text)" +
" }" +
"});";
se.eval(component);
}
// Render the component, which can be called multiple times
public void render(String text) throws Throwable {
String render =
"React.renderToString(React.createFactory(MyComponent)({" +
// using JSONObject here would be cleaner obviously
" text: '" + text + "'" +
"}))";
System.out.println(se.eval(render));
}
public static void main(String... args) throws Throwable {
Test test = new Test();
test.render("I want to Display");
test.render("This on a Browser like google chrome, using Tomcat server with Eclipse, currently it displays on Console in Eclipse.");
}
}
Many possibilities are there. One quite commonly used will be to go for REST services. You can host REST services using JAX-RS or Spring REST support. Put your web pages as a simple html page. Once this page will be loaded, it will make a REST call, will get the data and will show it to the user.
You can use JSP to do that..
Create a JSP page. Import the Test class.
You can check http://www.tutorialspoint.com/articles/run-your-first-jsp-program-in-apache-tomcat-server to know how to use JSP.

Android Web-View : Inject local Javascript file to Remote Webpage

It has been asked many times before, I browsed through everything, no clear answers yet.
Question simplified: Is it possible to inject local Javascript file (from asset or storage) to remote webpage loaded in an Android Web-View? I know that it is possible to inject such files to local Webpages (Assets HTML) loaded in a Web-View.
Why do I need this to work? : To make browsing experience faster, by avoiding downloading of bigger files such as Js and CSS files every time. I want to avoid Web-View Caching.
There is a way to 'force' the injection of your local Javascript files from local assets (e.g., assets/js/script.js), and to circumvent the 'Not allowed to load local resource : file:///android_assets/js/script.js ...' issue.
It is similar to what described in another thread (Android webview, loading javascript file in assets folder), with additional BASE64 encoding/decoding for representing your Javascript file as a printable string.
I am using an Android 4.4.2, API level 19 Virtual Device.
Here are some code snippets:
[assets/js/script.js]:
'use strict';
function test() {
// ... do something
}
// more Javascript
[MainActivity.java]:
...
WebView myWebView = (WebView) findViewById(R.id.webView);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);
myWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
injectScriptFile(view, "js/script.js"); // see below ...
// test if the script was loaded
view.loadUrl("javascript:setTimeout(test(), 500)");
}
private void injectScriptFile(WebView view, String scriptFile) {
InputStream input;
try {
input = getAssets().open(scriptFile);
byte[] buffer = new byte[input.available()];
input.read(buffer);
input.close();
// String-ify the script byte-array using BASE64 encoding !!!
String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
view.loadUrl("javascript:(function() {" +
"var parent = document.getElementsByTagName('head').item(0);" +
"var script = document.createElement('script');" +
"script.type = 'text/javascript';" +
// Tell the browser to BASE64-decode the string into your script !!!
"script.innerHTML = window.atob('" + encoded + "');" +
"parent.appendChild(script)" +
"})()");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
myWebView.loadUrl("http://www.example.com");
...
loadUrl will work only in old version use evaluateJavascript
webview.evaluateJavascript("(function() { document.getElementsByName('username')[0].value='USERNAME';document.getElementsByName('password')[0].value='PASSWORD'; "+
"return { var1: \"variable1\", var2: \"variable2\" }; })();", new ValueCallback<String>() {
#Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints: {"var1":"variable1","var2":"variable2"}
}
});
Yes, you could use shouldInterceptRequest() to intercept remote url loading and return local stored content.
WebView webview = (WebView) findViewById(R.id.webview);
webview.setWebViewClient(new WebViewClient() {
#Override
public WebResourceResponse shouldInterceptRequest (final WebView view, String url) {
if (url.equals("script_url_to_load_local")) {
return new WebResourceResponse("text/javascript", "UTF-8", new FileInputStream("local_url")));
} else {
return super.shouldInterceptRequest(view, url);
}
}
});
Be careful using evaluateJavascript: if there is a syntax error or exception thrown in your javascript it will call your onReceiveValue with a null. The most common way to support both SDK 19 as well as lower seems to be like this:Fill form in WebView with Javascript
Also if you get terribly desperate for some kind of browser functionality (in my case, never could figure out how to get DRM to work well) you could use a bookmarklet within normal chrome, which works only if you type the bookmark name into the omnibox but does work and does inject javascript.
Also be aware that with the default WebView you can't use javascript alerts to test anything, they don't show. Also be aware that "video" by default (like html <video> tags) doesn't "really work" by default and also DRM video doesn't work by default, they're all configure options :\

Extending Selenium RC with new methods

I am extending the selenium RC by using user-extension.js.
It is able to call the new method function, but throwing following error message.
*ERROR: Command execution failure. Please search the forum at http://clearspace.openqa.org for error details from the log window.
The error message is: Object doesn't support this property or
method*
As this program is executed on Google.com, any one can copy the sample code and execute on their respective PCs.
package package1;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.*;
import com.thoughtworks.selenium.*;
public class Sample2
{
private static final String Timeout = "30000";
private static final String BASE_URL = "http://google.com/";
private static final String BASE_URL_1 = "/";
private Selenium selenium;
private HttpCommandProcessor proc;
#BeforeClass
protected void setUp()throws Exception
{
proc = new HttpCommandProcessor("localhost", 4444, "*iexplore", BASE_URL);
selenium = new DefaultSelenium(proc);
selenium.start();
selenium.windowFocus();
selenium.windowMaximize();
selenium.windowFocus();
}
#AfterClass(alwaysRun=true)
protected void tearDown() throws Exception
{
selenium.stop();
}
#Test(groups="search")
public void test_GoogleSearch() throws Exception
{
selenium.open(BASE_URL_1);
selenium.type("name=q", "Bharath Marrivada");
//selenium.click("btnG");
proc.doCommand("myMethod",new String[] {"btnG"}); //user extension
Thread.sleep(5000);
}
}
user-extension.js
Selenium.prototype.doMyMethod = function(inputParams)
{
this.browserbot.click("btnG");
return null;
};
.js and Selenium JAR are in the same folder and executing the Selenium JAR using following command.
java -jar selenium-server.jar -userExtensions user-extensions.js
Any help on this issue?
It means that your command in user-extension file is not locating the element. Try running that in the IDE and check if it works fine
It works for me. Here is the modified user-extensions.js file code:
Selenium.prototype.doMyMethod = function(locator) {
var element = this.page().findElement(locator);
element.click();
};
Rest all remains the same. Hope this helps!!!

Conversion of table to Excel from JavaScript

I need to export my EditorGridPanel grid data to excel without sending any data to server-side, cross browser and cross platform solution that will work in ie6 and ie7. Any pure JavaScript solution is good as well!
So far i have found only data URI solution which is great but ie supports it only from 8-th version. Also there is a possibility to export through ActiveX component but it is not what i want since it makes my app depended to Windows and MSOffice.
Can you recommend me any solution ?
You could export to csv and then import that file into Excel , Open Office or Numbers?
Well after a wile of thinking i understood that this question is stupid because due to sandbox policy of js there is no possibility to export it directly from js.
As i said earlier i found some partial ways to do that:
ActiveX export and Data URI scheme
Here is a solution with a server-side call, but no server-side code writting.
http://code.google.com/p/gwt-table-to-excel/
The class below do that without server side.
public class TableToExcel {
public static final <T> void save(final CellTable<T> table, String filename) {
final AnchorElement a = Document.get().createAnchorElement();
a.setHref("data:application/vnd.ms-excel;base64," + base64(table.getElement().getString()));
a.setPropertyString("download", (filename.endsWith(".xls") || filename.endsWith(".xlsx")) ? filename : filename + ".xls");
Document.get().getBody().appendChild(a);
Scheduler.get().scheduleEntry(new ScheduledCommand() {
#Override
public void execute() {
click(a);
a.removeFromParent();
}
});
}
private static native void click(Element elem) /*-{
elem.click();
}-*/;
public static native String base64(String data) /*-{
return btoa(data);
}-*/;
}

Categories

Resources