I have an Android app which I am creating with the Kotlin
language. I am trying to get a specific <div>
element within the webpage I am displaying and then put the coordinates of the element into Kotlin
variables. In my case, I'm displaying a YouTube page and trying to get the coordinates of the video player (I will be later displaying a button over it). I'm using the following code to initialize my WebView
:
mainWebView.webViewClient = CustomWebViewClient(...) // This custom class doesn't do anything other than check if the user leaves the YT website.
mainWebView.webChromeClient = WebChromeClient()
mainWebView.settings.javaScriptEnabled = true
mainWebView.settings.domStorageEnabled = true
Then, I load the page:
mainWebView.loadUrl(";v=lh7WIW3pcso")
Next, I execute some JavaScript on the click of a specific button and display the result. I tested the JavaScript code in my browser's console and it worked fine. (It gave the result of {"x":0,"y":56}
.)
mainWebView.evaluateJavascript(
"(function() { var element = document.getElementById('full-bleed-container'); var rect = element.getBoundingClientRect(); return JSON.stringify({ x: rect.left, y: rect.top }); })();"
) { result ->
if (result == "null") {
Toast.makeText(this, "NULL!", Toast.LENGTH_SHORT).show()
} else {
val coordinates = JSONObject(result)
val x = coordinates.getDouble("x")
val y = coordinates.getDouble("y")
Toast.makeText(this, "Coordinates: X: $x, Y: $y", Toast.LENGTH_SHORT).show()
}
}
However, my app crashes with the following exception: .json.JSONException: Value {"x":0,"y":56} of type java.lang.String cannot be converted to JSONObject
.
I also checked to see if the page wasn't done loading with the following code (and I received the Toast
saying it was done):
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
Toast.makeText(context, "Loaded '$url'!", Toast.LENGTH_SHORT).show()
}
Why isn't the JSON response string being converted into the JSONObject
successfully? Not sure what's going on here, but I need to get the coordinates in such a format that I can display a button over that <div>
element.
EDIT----
Ok, so someone responded and linked me to this post which was kinda helpful (the only helpful post I found was this answer as all the rest showed things I'd tried already). So I tried Klaxon, and here's my code:
// For parsing
val coordinates = Klaxon().parse<JSONCoordinatesResponse>(result)
// Class that it puts the output into
class JSONCoordinatesResponse (val x: Int, val y: Int)
But it still throws an error when parsing the string:
java.lang.ClassCastException: java.lang.String cannot be cast to com.beust.klaxon.JsonObject
How can I parse this string into a Kotlin variables?