WebView, add local .CSS file to an HTML page?
Seva Alekseyev is right, you should store CSS files in assets
folder, but referring by file:///android_asset/filename.css
URL doesn't working for me.
There is another solution: put CSS in assets
folder, do your manipulation with HTML, but refer to CSS by relative path, and load HTML to WebView by loadDataWithBaseURL()
method:
webView.loadDataWithBaseURL("file:///android_asset/", htmlString, "text/html", "utf-8", null);
E.g. you have styles.css
file, put it to assets
folder, create HTML and load it:
StringBuilder sb = new StringBuilder();
sb.append("<HTML><HEAD><LINK href=\"styles.css\" type=\"text/css\" rel=\"stylesheet\"/></HEAD><body>");
sb.append(tables.toString());
sb.append("</body></HTML>");
webView.loadDataWithBaseURL("file:///android_asset/", sb.toString(), "text/html", "utf-8", null);
P.S. I've come to this solution thanks to Peter Knego's answer.
Load CSS file from assets to a WebView with custom HTML and predefined Base URL
If you want to intercept some of the requests from WebView
you can do so by overriding shouldInterceptRequest()
in WebViewClient
like this:
public WebResourceResponse shouldInterceptRequest (final WebView view, String url) {
if (URLUtil.isFileUrl(url) && url.contains(".css")) {
return getCssWebResourceResponseFromAsset();
} else {
return super.shouldInterceptRequest(view, url);
}
}
There is already an excellent detailed answer here https://stackoverflow.com/a/8274881/1112882
HOWEVER
You can not access local file if your base url is not local because of security reasons. So give relative path to your css and then intercept the request.
I would suggest using a pattern to differentiate b/w actual relative and custom relative paths. e.g. use android_asset/my_css_file.css
instead of my_css_file.css
and modify shouldInterceptRequest()
accordingly to always intercept requests starting from android_asset
.
inject CSS to a site with webview in android
You can't inject CSS directly however you can use Javascript to manipulate page dom.
public class MainActivity extends ActionBarActivity {
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
webView = new WebView(this);
setContentView(webView);
// Enable Javascript
webView.getSettings().setJavaScriptEnabled(true);
// Add a WebViewClient
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
// Inject CSS when page is done loading
injectCSS();
super.onPageFinished(view, url);
}
});
// Load a webpage
webView.loadUrl("https://www.google.com");
}
// Inject CSS method: read style.css from assets folder
// Append stylesheet to document head
private void injectCSS() {
try {
InputStream inputStream = getAssets().open("style.css");
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
inputStream.close();
String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
webView.loadUrl("javascript:(function() {" +
"var parent = document.getElementsByTagName('head').item(0);" +
"var style = document.createElement('style');" +
"style.type = 'text/css';" +
// Tell the browser to BASE64-decode the string into your script !!!
"style.innerHTML = window.atob('" + encoded + "');" +
"parent.appendChild(style)" +
"})()");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Rendering HTML in a WebView with custom CSS
You could use WebView.loadDataWithBaseURL
htmlData = "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />" + htmlData;
// lets assume we have /assets/style.css file
webView.loadDataWithBaseURL("file:///android_asset/", htmlData, "text/html", "UTF-8", null);
And only after that WebView will be able to find and use css-files from the assets directory.
ps And, yes, if you load your html-file form the assets folder, you don't need to specify a base url.
Android:How to refer css file within html in following situation
Try
link href="file:///sdcard/mibook/0.css"
Assuming Android >= 2.1
Load HTML in WebView with local css and js
Finally I have found the solution :
The css (or js) file is saved in local using this method :
public static void writeToFile(Context context, String content, String title) throws IOException
{
OutputStreamWriter osw = new OutputStreamWriter(context.openFileOutput(title,Context.MODE_WORLD_READABLE));
osw.write(content);
osw.close();
}Then I refer it in the html file using
<link rel="stylesheet" href="content.css" type="text/css" media="screen">
<script src="content.js"></script>And finally I have opened the webview using :
this.webView = (WebView) findViewById(R.id.webview);
this.webView.getSettings().setJavaScriptEnabled(true);
this.webView.getSettings().setPluginsEnabled(true);
this.webView.setHorizontalScrollBarEnabled(false);
this.webView.setVerticalScrollBarEnabled(true);
this.webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
this.webView.setWebViewClient(this.controller.getWebViewClient());
String basePath = "file://"+getFilesDir().getAbsolutePath()+"/";
this.webView.loadDataWithBaseURL(basePath, data, "text/html", "utf-8", "about:blank");
Related Topics
"An Internal Error Occurred" with Integration of Google Plus Login
Picasso Load Image from Filesystem
Set Limit on the Datepickerdialog in Android
Android Navigation Drawer Toggle Icon to Right
How to Write Vertically in a Textview in Android
Cursor Size Limit in Android SQLitedatabase
How to Find If a Particular Package Exists on My Android Device
How to Know When an Edittext Loses Focus
Android Ci Build: Could Not Find Aapt2-Proto.Jar
Connecting Mongodb from Mobile or Browser Based Application
Read the Package Name of an Android APK