I have some difficulties when trying to pass data to my html file. My html file is located at project root inside assets folder. In short, i am displaying my html file inside a webView.
This is portion of my mainActivity.kt, which is used to populate my webView
mWebView = findViewById(R.id.activity_main_webview);
val webSettings = mWebView.settings
webSettings.javaScriptEnabled = true
mWebView.loadUrl("file:///android_asset/googlechart.html");
and here is portion of my googlechart.html, which is stored locally inside assets folder
var dataRow = [["mushroom", 1], ["fish", 3]]
var data = new google.visualization.DataTable();
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
data.addRows(dataRow);
I want to pass data from mainActivity.kt to my googlechart.html, per answer at Passing data from java class to Web View html, it didn't explain how to pass data to a html file which is stored inside project root. How can i achieve that ?
Any help or insight is appreciated.
Simple solution
use Query when loadUrl()
get document.location.href in script
deal with your data
decode string, split, etc
example
If data is json
android
val json = JsonObject().apply {
addProperty("age","28")
addProperty("name","john")
addProperty("contents","test")
}
val url = "file:///android_asset/test.html?$json"
binding.webView.loadUrl(url)
local .html
<!DOCTYPE html>
<html>
<body>
<H1>test</H1>
<oi id="list">
</oi>
<script type="text/javascript">
function makeList() {
const getOiTag = document.getElementById("list");
const decodeUrl = decodeURI(document.location.href);
const jsonStr = decodeUrl.split("?")[1];
const json = JSON.parse(jsonStr);
for(i in json){
const li = document.createElement("li")
li.textContent = i + " : " + json[i];
getOiTag.appendChild(li);
}
}
makeList()
</script>
</body>
</html>
Related
i have the following html code :
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body >
<iframe id="pic" src="http://rtsp.me/embed/883assBN/" width="450" height="254" frameborder="0" scrolling="no"></iframe>
</body>
</html>
When the page loads there is a play button that when it is pressed it starts playing a video. When it is pressed on the chrome network tab there is a GET request with the following URL : " https://frn.rtsp.me/xAbXuzHiF6P3Hi8P7fK4_A/1598176697/hls/883assBN.m3u8 " .
The problem is after /frn.rtsp.me the sentences are being dynamically changed over some period of time for example :
https://frn.rtsp.me/XXX/XXX/hls/883assBN.m3u8
and i cannot obtain the new ones without using the provided html code and check the get requests in Chrome. My goal is to play the m3u8 video in a exoplayer on a Android device and what is the best way to view the get requests there from a webView or is there any other way to obtain the m3u8 playlist?
Best regards!
if anyone else is facing a similar issue here is my solution:
val embedUrl = "https://rtsp.me/embed/883assBN/"
try {
val html: Connection.Response = Jsoup.connect(embedUrl).execute()
val statusCode = html.statusCode()
if (statusCode == 200) {
val dok: Document = Jsoup.parse(html.body(), embedUrl)
val scripts : Elements = dok.getElementsByTag("script")
val urlScript : String = scripts.last().toString()
val start_idx = urlScript.indexOf("https://")
val end_idx = urlScript.indexOf(";")
var tmp = urlScript.substring(start_idx,end_idx)
val result = tmp.replace("\"","")
}
} catch (e: IOException) {
e.printStackTrace()
}
I've seen multiple tutorials adding a GetBaseUrl separately for IOS and Android, but they don't answer my question. I was wondering if there is no other way to add custom CSS to a webview and only use 1 stylesheet (default.css). The reason why I want to do this is because my stylesheet is identical for both IOS and Android and contains little styling.
This is what I've tried:
I have a WebView:
<WebView.Source >
<HtmlWebViewSource Html="{Binding Data.Content}" />
</WebView.Source>
The Source of this WebView is a string that looks like this:
string contentString = #"<html>
<head>" +
"<link rel='stylesheet' href='default.css'"
"</head>" +
"<body style='text-align:left;background-color:white;font-size:16px;margin:0;'>" +
value +
"</body>" +
"</html>";
The default.css file mentioned above is in my Assets folder and has Build Action EmbeddedResource, located in the root directory of my project:
Can anyone help? Thanks in advance.
There are some ways to do this, one is to use HtmlWebViewSource, the html is like this:
htmlSource.Html = #"<html>
<head>
<link rel=""stylesheet"" href=""default.css"">
</head>
<body>
<h1>Xamarin.Forms</h1>
<p>The CSS and image are loaded from local files!</p>
<img src='XamarinLogo.png'/>
<p>next page</p>
</body>
</html>";
Another way is to use WebView.loadDataWithBaseURL, there is the same thread that you can take a look:
Rendering HTML in a WebView with custom CSS
The easiest way is to wrap your HTML with CSS (or replace link tags with its resulting content)
var html = AddHtmlAndCssTags("<div>my html</div>", ReadCss());
protected string ReadCss()
{
var resourceName = $"MyProj.Resources.Css.article.css";
var isExists = ResourceLoader.IsEmbeddedResourceExists(Assembly.GetAssembly(typeof(ResourceLoader)), resourceName);
if (isExists)
{
return ResourceLoader.GetEmbeddedResourceString(Assembly.GetAssembly(typeof(ResourceLoader)), resourceName);
}
return string.Empty;
}
protected string AddHtmlAndCssTags(string html, string css)
{
var cssTag = string.IsNullOrEmpty(css) ? string.Empty : $"<style>{css}</style>";
return $"<html><head>{cssTag}</head><body>{html}<body></html>";
}
I am using jsoup to parse html and webview to display html content. In the process I am changing the source for a image. So when in html this line is executed <img src="sdcard/rreadyreckoner_images/download-r.png" alt="downloadr" width="191" height="129" />
the image doesn't load i.e. the there is space left for the image but it does not contain the actual image. How can I achieve this in android?
This is the code I am using.
private void showJson(String json) {
ParseJSON pj = new ParseJSON(json);
pj.parseJSON();
String[] instruction = ParseJSON.instruction;
for (int i = 0; i < instruction.length; i++)
{
Document doc = Jsoup.parse(instruction[i]);
if (doc.select("img[src]").attr("src").contains("download-r.png"))
{
Elements image = doc.select("img[src]");
String imgsource = image.attr("src");
downloadImages(imgsource);
Boolean isSDPresent = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
if (isSDPresent)
{
image.attr("src","sdcard/rreadyreckoner_images/download-r.png");
}else
{
image.attr("src","/storage/emulated/0/rreadyreckoner_images/download-r.png");
}
}
Log.d("Clean", String.valueOf(doc));
// String imgsrc = images.attr("src");
webView.getSettings().setJavaScriptEnabled(true);
webView.loadData(String.valueOf(doc),"text/html","UTF-8");
Elements paragraphs = doc.select("ul li ");
for (Element element: paragraphs)
{
Log.d("PARAGRAPHS",element.text());
}
//Log.d("SOURCE",imgsrc);
//Toast.makeText(MainActivity.this, imgsrc, Toast.LENGTH_SHORT).show();
}
}
This is the html that I am trying to display in a webview.
<html>
<head></head>
<body>
<ul>
<li>The Comprehensive R Archive Network</li>
<li>A network of global web servers storing identical, up-to-date, versions of<br />code and documentation for R</li>
</ul>
<p><br /><strong>Download and Install R:</strong></p>
<ul>
<li>Use the CRAN mirror nearest to you to download R setup at a faster<br />speed. Go to http://cran.r-project.org</li>
<li>Select one of the three download links according to your machine.</li>
</ul>
<img src="sdcard/rreadyreckoner_images/download-r.png" alt="downloadr" width="191" height="129" />
<ul>
<li>Run the R set up and follow the instructions of the installer.</li>
</ul>
</body>
</html>
I get the follwoing error
chromium: [INFO:CONSOLE(1)] "Not allowed to load local resource:
file:///sdcard/rreadyreckoner_images/download-r.png"
you have to use Environment.getExternalStorageDirectory() to get the real path of the sdcard:
Boolean isSDPresent = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
if (isSDPresent)
{
image.attr("src", Environment.getExternalStorageDirectory() + "/rreadyreckoner_images/download-r.png");
}else
{
image.attr("src","/storage/emulated/0/rreadyreckoner_images/download-r.png");
}
I suggest to load the image into your WebView this method:
myWebView = (WebView) findViewById(R.id.webview);
myWebView.getSettings().setAllowFileAccess(true);
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.getSettings().setBuiltInZoomControls(true);
String imagePath = "file://"+ Environment.getExternalStorageDirectory().getAbsolutePath() + "rreadyreckoner_images/download-r.png";
//Create an html template.
String html = "<html><head></head><body><img src=\""+ imagePath + "\"></body></html>";
//Load the image into your WebView:
mWebView.loadDataWithBaseURL("", html, "text/html","utf-8", "");
Question 1:
I'm trying to make an android application with python and WebView.
I wonder if I can get a python variable and send it to html and save them in a variable in javascript.
I tried this but does not work:
script.py
import android
import os, sys
ruta_del_proyecto = os.path.dirname(os.path.realpath(__file__))
droid = android.Android()
droid.webViewShow(ruta_del_proyecto + '/ui/prueba.html?ruta_del_proyecto=5')
print ruta_del_proyecto + '/ui/prueba.html?ruta_del_proyecto=5'
prueba.html
<html>
<!--urta cel: file:///sdcard/sl4a/scripts/test1/ -->
<head>
<title>prueba</title>
<script>
var droid = new Android();
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
vars[key] = value;
});
return vars;
}
var ruta_del_proyecto = getUrlVars()["ruta_del_proyecto"];
alert (ruta_del_proyecto);
</script>
</head>
<body>
</body>
</html>
Question 2:
When I make the script.py in to APK with "The Android Java IDE (AIDE)" , then install and open, WebView don't open
The python code are execute but WebView don't open
Any idea?
There is a simple hack you can do. Webkit WebView has the "load-finished" event that triigers after your page loads and after which you can execute your JavaScript function:
def on_load_finished(webview, frame):
browser.execute_script('your-js-function('+yourVariable+');')
browser = webkit.WebView()
browser.connect("load-finished", on_load_finished)
Remember, you can pass dictionaries as an argument by serializing them with json module and deserializing them in JS!
I can show up HTML file content in android webview well.Now how could i pass parameter into HTML file.For ex.my HTML content has an video player
i need to pass dynamic values(URL) into HTML file for playing dynamic video.My HTML file is located on asset folder.How could i do this?
Thanks.
I came upon this problem today, however I needed this to work with UTF-8 encoding, so this was my approach, hopefully it will help someone and clarify some of the previous answers to this question.
HTML:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<h1>%ERR_TITLE%</h1>
<h2>%ERR_DESC%</h2>
</body>
</html>
Java:
String content = IOUtils.toString(getAssets().open("error.html"))
.replaceAll("%ERR_TITLE%", getString(R.string.error_title))
.replaceAll("%ERR_DESC%", getString(R.string.error_desc))
mWebView.loadDataWithBaseURL("file:///android_asset/error.html", content, "text/html", "UTF-8", null);
As for IOUtils:
http://commons.apache.org/proper/commons-io/download_io.cgi
Instead of passing directly the video URL (following you example), i would have used tokens in the Html file. For example:
<embed src="$VIDEO_URL$" autostart="false" />
where the $VIDEO_URL$ will be the token wich will be replaced during the runtime with a real video URL.
Also, since you cannot change the contents of your asset folder during runtime you should load the html file contents into a String variable and use the replace method to replace the token with a real URL and, finally, pass that string to your webview. Something like this:
//The html variable has the html contents of the file stored in the assets folder
//and real_video_url string variable has the correct video url
html = html.replace("$VIDEO_URL$", real_video_url);
webview.loadData(html, "text/html", "utf-8");
If i would like to have something dynamic in my HTML i would have an html with dynamic parts written like this:
<B>%NAME%</B>
Then i would load my HTML:
String template = Utils.inputStreamToString(assets.open("html/template.html"));
then
Then i would replace all dynamics parts with what i want like this:
String data = template.replaceAll("%NAME%", "Alice McGee");
then i would pass it to my webView!
WebView webView = new WebView(this);
webView.loadDataWithBaseURL("file:///android_asset/html/", data, "text/html", "utf-8", null);
I managed to pass variables in a different way.
My problem was that everytime I switched to another app, when coming to the webapp, the webview kept reloading. I guess that's because of the following line in my onCreate() method: myWebView.loadUrl(url); I had the idea to pass these state variables in the url, but as you know it is not possible yet.
What I did was to save the state of some variables using onSaveInstanceState(Bundle outState) {...} and restore them with onRestoreInstanceState(Bundle savedInstanceState){...}.
In onCreate method after setting up myWebView I did the following:
myWebView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String urlString)
{
Log.i("onPageFinished", "loadVariables("+newURL+")");
if(newURL!="")
myWebView.loadUrl("javascript:loadVariables("+"\""+newURL+"\")");
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
jsInterface = new JSInterface(this,myWebView);
myWebView.addJavascriptInterface(jsInterface, "Android");
if (savedInstanceState != null)
{
// retrieve saved variables and build a new URL
newURL = "www.yoururl.com";
newURL +="?var1=" + savedInstanceState.getInt("key1");
newURL +="?var2=" + savedInstanceState.getInt("key2");
Log.i("myWebApp","NEW URL = " + newURL);
}
myWebView.loadUrl("www.yoururl.com");
So, what it happens is that first I load the page with the default URL (www.yoururl.com) and onPageFinished I call a new javascript method where I pass the variables.
In javascript loadVariables function looks like this:
function loadVariables(urlString){
// if it is not the default URL
if(urlString!="www.yoururl.com")
{
console.log("loadVariables: " + urlString);
// parse the URL using a javascript url parser (here I use purl.js)
var source = $.url(urlString).attr('source');
var query = $.url(urlString).attr('query');
console.log("URL SOURCE = "+source + " URL QUERY = "+query);
//do something with the variables
}
}
here assets means what?
String template = Utils.inputStreamToString(assets.open("html/template.html"));