I've seen several questions on this but all of the solutions didn't work for me. For a client we have to develop an app that actually does nothing except of showing a WebView
and a native DrawerLayout
. However, we only have their mobile webpage (with a menu, etc.). So we have to hide some elements. It is very important that the existing stylesheets stay the same, just some other CSS
rules are added.
What I've tried so far:
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (!mErrorOccured && !noConnectionAvailable) {
injectCSS();
}
mainActivity.hideLoadingScreen();
}
With this Injection:
// Inject CSS method: read style.css/readmode.css from assets folder
// Append stylesheet to document head
private void injectCSS() {
try {
Activity activity = (Activity) mContext;
SharedPreferences sharPref = activity.getSharedPreferences(Constants.PREFERENCE_NAME, Context.MODE_PRIVATE);
Boolean isReadMode = sharPref.getBoolean(Constants.READMODE_KEY, false);
InputStream inputStream;
if (isReadMode) {
inputStream = activity.getAssets().open("readmode.css");
} else {
inputStream = activity.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);" +
"Android.injectCSS('Works!');})()");
} catch (Exception e) {
e.printStackTrace();
}
}
I've also tried to add a JavaScript Interface that uses the Android.injectCSS('Works!');
of the JavaScript above combined with:
@JavascriptInterface
public void injectCSS(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_LONG).show();
mMainActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mMainFragment.unhideWebView();
}
});
}
And:
public void unhideWebView() {
webView.setVisibility(View.VISIBLE);
}
However, there is always a delay before the elements of the web page are hidden. I've also tried to use Jsoup
. First this threw an NetworkOnMainThreadException
. After I've tried to use it with an AsyncTask, it was not possible to change the WebView
on onPostExecute()
because this handling must be on the main thread. Even using a runOnUiThrad()
did not help calling loadData()
on the WebView
with the new loaded data.
Is there any way to inject CSS/JS before the WebView
shows up?