Unable to access HTML element values(Webview) through Monoandroid.
Context: - The Monoandroid App we are developing has a Webview Component in one of the layouts. We are loading/reusing our existing (registration page) HTML/JavaScript: having radio buttons(Male/female rdBtns).
But not able to access the selected radioButton values on "Submit" Button(outside the webview) click event.
Tried using the JavaScriptInterface with WebView,but not available.
Got the Value to a Java class through JNI, there to my C#(Unsuccessful)
Assumptions for the issue:
No Klue.
Question:
How can i get the value to mono event code?
Please suggest some alternative way to access the HTML element value outside the webview through MONODROID?
You should capture all request that are send by the website inside your webview like the submit of the data you`re interested in. Therefore you should add a WebViewClient to your WebView and implement
public bool ShouldOverrideUrlLoading (WebView view, string url)
Here is an example that I`m using to get the id of the currently (in the webview) selected feature of a map that is inside a WebView to display the corresponding details the user requested by clicking this object on the map.
The JavaScript-Code is just the href that is calling a function:
"Details...";
This is the function (where eventFeature is a global variable)
function getDetailsForSelectedStation() {
window.location.href = "www.ANFANGP" + eventFeature.attributes.saeulenid + "PDETAILANFRAGE";
}
(You could also directly set the href to our "fake"-url)
It should start like a usual adress so I used www. and then I used P to be able to tokenize the string in C#. The End-Tag "DETAILANFRAGE" will be used to catch this call in C#.
Now this is the WebViewClient to receive the message:
class MyWebViewClient : WebViewClient
{
public override bool ShouldOverrideUrlLoading (WebView view, string url)
{
//check, whether this was a details-url
if (url.EndsWith ("DETAILANFRAGE")) {
//tokenize the url
string[] tokens = url.Split ('P');
long saeulenid;
if (long.TryParse (tokens [1], out saeulenid)) {
//Here you can work with the data retrieved from the webview
ShowDetailsByID(saeulenid);
...
}
}
return true;
}
}
The WebViewClient has to be added to the WebView:
MyWebView.SetWebViewClient(new MyWebViewClient());
If you need more context information you should override the constructor, too. I`m handing over the current activity to be able to start a new Activity (StartActivity() ) to display a view for details in my app.
By the way, to call JavaScript code from C# you just have to load an url like:
MyWebView.LoadUrl("javascript:myFunction(myParams)");
Very useful for debugging is the WebChromeClient.
See this tutorial from xamarin for more details
And of course you may find interesting information in the WebView reference
Related
I have a web page, when on button click returning javascript object.
<input type="button" value="JSON Object" onclick="JSONObjectTest(user1)"
var user1 = { "name" : "myname", "title": "mytitle", "salary" : null};
In C# application, I am loading this web page which contains the above code using web browser. And implemented the below code in C#
this.webBrowser.ObjectForScripting = new JavascriptEventHandler();
This code in DocumentCompleted
var scriptBlock = webBrowser.Document.CreateElement("script");
var sb = new StringBuilder();
sb.Append("window.JSONObjectTest=function(param){window.external.JSONObjectEvent(param);}");
scriptBlock.SetAttribute("type", "text/javascript");
scriptBlock.SetAttribute("text", sb.ToString());
webBrowser.Document.Body.AppendChild(scriptBlock);
This is code for JavascriptEventHandler(ObjectForScripting) Class
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
[ComVisible(true)]
public class JavascriptEventHandler
{
public void JSONObjectEvent(object param)
{
}
}
I was able to load the web page perfectly. And when a button is clicked on webpage I was able to hit this method - JSONObjectEvent in C#.
My problem here is, I want to deserialize the javascript object into c# class. I am getting object type as System._COMObject.
How to deserialize it? Please help.
Using Newtosnsoft.Json to deserailize.
NOTE : I will be getting javascript object only not in string. If I pass JSON.Stringify(user1) from web page, I can able to deserialize it. But if it is javascript object I cannot able to deserialize.
I am new to this so could anyone point me to the right direction?
I have a JavaScript file by which i want to take the value of a span from a website. Now the website dynamically refreshes the span every 1 second. I am using Java (Eclipse) to fetch this data. When i try to take the span value from website, it gives me no values because the span uses JavaScript to store these values. I already asked this question and i will drop a link below. So all i want to know is, how to take this data dynamically using JSoup. Someone commented on my last post saying the JavaScript might be querying a web service and to find that code. But i could not find the code and i don't know what to do next.
Here is the link to my last question: Fetching Dynamic Website Data Using Java
Here is the link to the website which stores data i want in a span named "id=spot" (Basically numeric numbers of stock): https://www.binary.com/trading?l=EN
And finally here is the link to the JavaScript file of the website which have all the functions: https://static.binary.com/js/binary.min.js?13b386b
Please help me as i am very new to this and i have spent more than 2 days trying to find the answer with no luck.
Thank you in advance
--------------------------------------------------------------------------------.---------------------------------------------------
Okay so the first part of the question is solved but i am having another issue now. I copied this code but i am getting this error now. Here is my code:
import java.net.URI;
import java.io.IOException;
import java.lang.InterruptedException;
import javax.websocket.*;
#ClientEndpoint
public class WSClient {
#OnOpen
public void onOpen(Session session) throws java.io.IOException
{
session.getBasicRemote().sendText("{\"ticks\": \"R_100\"}");
}
#OnMessage
public void onMessage(String message)
{
System.out.println("ticks update: " + message);
}
public static void main(String[] args)
throws IOException, DeploymentException, InterruptedException
{
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
URI apiUri = URI.create("wss://ws.binaryws.com/websockets/v3");
Session session = container.connectToServer(WSClient.class, apiUri);
Thread.sleep(10000);
}
}
And here is the error on console:
Exception in thread "main" java.lang.RuntimeException: Could not find an implementation class.
at javax.websocket.ContainerProvider.getWebSocketContainer(ContainerProvider.java:73)
at WSClient.main(WSClient.java:24)
This site is using WebSockets to retrieve the data from server to show in the client:
var onLoad = function(){
trading_page = 1;
if(sessionStorage.getItem('currencies')){
displayCurrencies();
}
BinarySocket.init({
onmessage: function(msg){
Message.process(msg); //this function is updating that sppan
},
onclose: function(){
processMarketUnderlying();
}
});
Price.clearFormId();
TradingEvents.init();
Content.populate();
So you can not see the data in downloaded HTML with JSOUP. You need a UI-less Browser in java like HTML-UNIT.
But the preferred and more reasonable way is to use the API of the site.
I wanted to know if there is a way to do similar code in java servlet like I do in express.js
In express I can say for example:
app.get('/:name',function(bla bla)){}
the :/name its a parameter in which the url of the get can be
localhost/kevin
localhost/joe
or whatever... This is great because I can take then for example that name (request.params.name) and so something with it. And it is also great because there is no limit(As far as I know) as to how many routes I can create, it just serves as a placeholder.
Is there a way I can do this using Java servlets?? I want to be able to have an html page that when I click a button it goes to localhost/button1 If I click another button it goes to localhost/button2.. and so on.. But also I'm letting the user create buttons dynamically so I don't want to create jsp pages beforehand, I just want the servletto create one..?
Thanks
Almost. With help of a prefix mapping /foo/* and HttpServletRequest#getPathInfo().
#WebServlet("/name/*")
public class NameServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getPathInfo().substring(1);
// ...
}
}
Invoke it as
http://localhost:8080/context/name/kevin
http://localhost:8080/context/name/joe
...
You can optionally map the servlet on /*, but then it will act like a global front controller which isn't necessarily a good idea as you'd have to take static resources like CSS/JS/images and such into account.
In case you actually intend to create a REST service, rather look at JAX-RS instead of "plain vanilla" servlets. It would further reduce boilerplate code. See also a.o. Servlet vs RESTful.
I am using Liferay Portal 6.2 CE GA3
I need to call my custom portlet resource method from another portlet jsp file. Below is my code.
Click here
<script>
function myfunction(myVar){
AUI().use('aui-base','aui-io-request','liferay-portlet-url','aui-node',function(A){
var url = Liferay.PortletURL.createResourceURL();
url.setPortletId("MyCustomPortletId");
url.setResourceId('saveUserData');
A.io.request(url);
});
}
and my custom portlet ...
public class MyCustomPortlet extends MVCPortlet{
public void saveUserData(ResourceRequest resourceRequest,
ResourceResponse resourceResponse) throws IOException,
PortletException {
System.out.println("in save UserData");
}
render method----
}
Here serveResource method (in my case saveUserData ) is not getting called. Any suggestions ?
Did you try calling your method from your own custom portlet just to be sure your saveUserData method is being called and has no issues?
Please try and then read forward if it does not work ;-)
serveResource method is always named as serveResource and not by any other name as saveUserData when you use Liferay's MVCPortlet.
You cannot have multiple serveResource methods as you can have action methods.
So rename your method to serveResource() and it should work :-)
I am writing a tiny MVC app that is a utility to simulate the actions of getting an id from a portal and setting it in a database for another app to obtain while this app is open. I attempted to write it using ASP.NET MVC to "get my feet wet." In it, I am attempting to use the JavaScriptResult (DESPITE all the warnings) to execute Javascript's window.open function but I get only a file dialog that is acting like the FilePathResult - it displays a dialog box asking if I want to save my file which is the name of the ActionEResult. How do I do this?
public JavaScriptResult SessionTransferDesktop(string PortalUserId)
{
/// .... Call Oracle SP to set token
// Redirect to RON Scheduler
string js = "window.open('/RONSchedulerMVC/default.aspx?p_token=' + portalToken);";
// string js ="window.open('http://microsoft.com')";
return JavaScript(js);
}
public ActionResult SessionTransferDesktop(string PortalUserId)
{
/// .... Call Oracle SP to set token
// build url and redirect
var uriBuilder = new UriBuilder("http://example.com");
uriBuilder.Path = "/RONSchedulerMVC/default.aspx";
uriBuilder.Query = "p_token=" + Url.Encode(portalToken);
return Redirect(uriBuilder.ToString());
}
You are getting the file result because your browser is requesting something and getting content-type:application/javascript back.
The easiest way to get this to work is to simply make the route redirect the response to the portal. You can then just call window.open directly on said route and profit.