im trying to use WebView like this:
String html = " <html><body>
<table style\"background-color: #0a82a4; color: #ffffff;\">
... stuff ...
</table>"
</body>
</head>";
html.replace("#", "%23");
html.replace("\\", "%27");
html.replace("?", "%3f");
html.replace("%", "%25");
myWebview.loadData(html, "text/html", "utf-8");
It Works, but when add width=100% in style tag, webView cant load the data.
I used this reference: http://developer.android.com/reference/android/webkit/WebView.html#loadData(java.lang.String, java.lang.String, java.lang.String)
loll, solved:
html = html.replace("%", "%25");
html = html.replace("#", "%23");
html = html.replace("\\", "%27");
html = html.replace("?", "%3f");
Have you seen the HelloWorld example in the devguide located here
To solve this, I changed the order of replace calls:
html = html.replace("%", "%25");
html = html.replace("#", "%23");
html = html.replace("\\", "%27");
html = html.replace("?", "%3f");
Related
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>
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>";
}
This question already has answers here:
Android Development: Using Image From Assets In A WebView's HTML
(6 answers)
Closed 8 years ago.
I have few image in asset folder!
I want to use these image path for img tag in html!
I use below code for get path but it doesn't work.
String p="file:///android_asset/img.jpg";
what can I do?
this is my code
String p="file:///android_asset/img.jpg";
String html = "<html dir=\"rtl\" lang=\"fa-IR\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=1\"></head><body class=\"rtl single single-post postid-38 single-format-standard custom-background\"></h3><center>MY TEXT<br><img src="+p+" /><hr>FOOTER<hr></center></body></html>";
my problem is src=p , because this app can't load image!
Try this way its working for me
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String sHtmlTemplate = "<html><head></head><body><img src=\"file:///android_asset/ic_launcher.png\"><p>Hello Webview.</p></body></html>";
WebView wb = new WebView(this);
wb.loadDataWithBaseURL(null, sHtmlTemplate, "text/html", "utf-8",null);
setContentView(wb);
}
}
Output:
this is my code
String p="file:///android_asset/img.jpg";
String html = "<html dir=\"rtl\" lang=\"fa-IR\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=1\"></head><body class=\"rtl single single-post postid-38 single-format-standard custom-background\"></h3><center>MY TEXT<br><img src="+p+" /><hr>FOOTER<hr></center></body></html>";
my problem is src=p , because this app can't load image!
You need to assign the same string to src attribute in img tag like :
<img src="file:///android_asset/img.jpg" ... >
If it is in a variable assing it as :
<img src="+filename+"... >
I don't have a html file & i make html and load it from string at runtime
String filename ="file:///android_asset/img.jpg";
String htmlString= "<html><img src="+ filename +" height='100%' width='100%'></html>"; // whatever is your html text
wb.loadUrl(htmlString);
For more information, refer this
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"));
I'm loading an html asset page into a WebView using
webMain.loadUrl("file:///android_asset/record.html");
which works fine, but inside the html are a number of places where I'd like to use information from the app. For instance, the HTML may contain text that reads "[Custom]". Is there a way I can replace that word with information passed from the application?
This is an old and already accepted question, however I am sure that the problem can be solved in more elegant way by using javascript.
Keep the html file in your assets folder and surround the text which you want to replace into with div elements with unique id's.
<html>
<head> ... <head>
<body>
Static text
<div id="replace1">replace me</div>
<div id="replace2">replace me too</div>
More static text ...
</body>
</html>
Now create a javascript function which will replace the innerHtml of a div with an id:
function replace(id, newContent)
{
document.getElementById(id).innerHTML = newContent;
}
This function will be best placed directly in the html file, update the <head> section to look like this:
<head>
...
<script type="text/javascript">
function replace(id, newContent)
{
document.getElementById(id).innerHTML = newContent;
}
</script>
</head>
Now we need to call the javascript function from from the WebView Android api:
WebView helpView = (WebView)findViewById(R.id.helpView);
helpView.getSettings().setJavaScriptEnabled(true);
helpView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
view.loadUrl("javascript:replace('replace1', 'new content 1')");
view.loadUrl("javascript:replace('replace2', 'new content 2')");
}
});
helpView.loadUrl("file:///android_asset/help.html");
Using this you will avoid reading potentially large data into memory and running expensive operations on it unnecessarily.
This is worked for me.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Payment Demo</title>
</head>
<body>
<div>
<input type="text" id="uname " name="uname " value="">
<input type="text" id="pass" name="pass" value="">
</div>
</body>
</html>
This is java code.
WebView wb = (WebView) findViewById(R.id.webView1);
wb.loadUrl("file:///android_asset/web1.html");
wb.getSettings().setJavaScriptEnabled(true);
wb.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView web, String url) {
// TODO Auto-generated method stub
String uname = "email#mail.com";
String pass = "******";
web.loadUrl("javascript:(function(){document.getElementById('uname').value = '"+uname+"';})()");
web.loadUrl("javascript:(function(){document.getElementById('pass').value = '"+pass+"';})()");
}
});
Actually I do not understand why the file size of record.html will affect maintainence of the code. Read the html string (using Java reader class or what ever) from the html file in asset, use replaceAll function with Regex to replace all the [Custom] in the html file. How long the html is should not really affect how you maintain the code. It should rather be a performance problem, or the string is really really long that exceeds the java String limit.
some code I have used before :
InputStream is = getApplicationContext().getAssets().open("details/product_jsmodify.html");
Reader r = new InputStreamReader(is);
String details = Utils.readertoString(r);
details = details.replace("%product_name%",productName );
Utils is my class doing the conversion to string. I am not using Regex here as I am only replacing word for once. Then I load the string like Cata does. It is quite clean I suppose.
Yes you can do that by loading your page in a String and then load that string in your WebView.
Eg:
String summary = "<html><body>You scored <b>192</b> points.</body></html>";
webview.loadData(summary, "text/html", null);
Taken from here
This one worked for me, with the html along with the text and images.
InputStream is = getAssets().open(html_name);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
String str = new String(buffer);
str = str.replace("InitialTextToBeReplaced", "TextAfterReplacement");
//Now instead of webview.loadURL(""), I needed to do something like -
webView.loadDataWithBaseURL("file:///android_asset/", str, "text/html", "UTF-8",null);