Webview, Add Local .CSS File to an HTML Page

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



Leave a reply



Submit