Skip to content

Work with Webview in Android

vuvanly edited this page May 26, 2015 · 13 revisions

Deal with Audio problem

Play and Pause audio inside webview:

When you have an audio tag in webview content, the audio is played, you pressed the pause button and you want to pause the audio. Here are the code that you can use to do that:

WebView wvQuestion;
String javascript="javascript: document.getElementsByClassName('audio')[0].pause();";
wvQuestion.loadUrl(javascript);

If you want to play the audio, just replace the pause with play. Here, audio tag has class audio.

The audio cannot play in Android 4.0 ~ 4.3

When i load the html file has audio tag, the phone with Android version > 4.3 can work well but the phone with lower version cannot play audio. So the problem is the Webview has some change from Android 4.3 to 4.4. And one more problems here is that i put the html file inside Internal Storage so that it cannot be loaded. So i move the html file into External Storage and the problem is solved.

#Cache the website Many apps have the homepage website for that app, so we often have one page for WebActivity. Normally, we need internet to load the webpage, but the problem here is that when network is available i want load webpage from network, and when network the isn't available i want to load it from local cache. One more thing that i want preload the webpage from previous Activity as well. So below is what i do:

   public static DialogFragment errorDialog;
   public static void loadWebCache(String url, final Context context, final FragmentManager fragmentManager) {
        final Intent webIntent = new Intent(context, WebActivity.class);
        final WebView webView = new WebView(context);
        webView.getSettings().setAppCacheMaxSize(APP_CACHE_SIZE);
        webView.getSettings().setAppCachePath(context.getApplicationContext().getCacheDir().getAbsolutePath());
        webView.getSettings().setAllowFileAccess(true);
        webView.getSettings().setAppCacheEnabled(true);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
        if (!ICTEL.isNetworkAvailable(context)) { // loading offline
            webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ONLY);
        } else {
            ICTEL.showLoadingDialog(context);
        }

        webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onReceivedError(WebView view, int errorCode,
                                        String description, String failingUrl) {
                webIntent.putExtra("can_load", false);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                ICTEL.dismissLoadingDialog();
                if (!webIntent.getBooleanExtra("can_load", true)) {
                    errorDialog = new CustomAlertDialog();
                    Bundle errorBundle = new Bundle();
                    errorBundle.putString(ICTEL.TITLE, context.getResources().getString(R.string.text_error_title));
                    errorBundle.putString(ICTEL.ERROR_MESSAGE, context.getResources()
                            .getString(R.string.msg_network_error));
                    errorDialog.setArguments(errorBundle);
                    ICTEL.addFragmentOnlyOnce(fragmentManager, errorDialog, ICTEL.ERROR_MESSAGE);
                } else {
                    webIntent.putExtra("url", url);
                    webIntent.putExtra("title", view.getTitle());
                    context.startActivity(webIntent);
                }
            }
        });
        webView.loadUrl(url);
    }

And we will call the above method when we click to item to change to WebviewActivity. PreviousActivity

ICTEL.loadWebCache(ICTEL.HOME_PAGE, context, getChildFragmentManager());

In the method onCreate of WebviewActivity to load Webview from Cache.

        String url = getIntent().getStringExtra("url");
        webView = (WebView) findViewById(R.id.wv_content);        
        webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        webView.loadUrl(url);

Make the web content fit width.

Layout activity_web.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    tools:context="jp.co.asto.ictel.views.WebActivity">
   
    <WebView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/wv_content">
    </WebView>
</RelativeLayout>

And we config the WebSetting of Webview:

        Webview webView = (WebView) findViewById(R.id.wv_content);

        webView.setInitialScale(1);
        webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);   // Fix the bug webview doesn't wrap text correctly
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setDomStorageEnabled(true);
        webView.getSettings().setLoadWithOverviewMode(true);
        webView.getSettings().setUseWideViewPort(true);
        webView.getSettings().setSupportZoom(true);
        webView.getSettings().setBuiltInZoomControls(true);
        webView.getSettings().setDisplayZoomControls(false);
        webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        webView.setScrollbarFadingEnabled(false);

Show Pdf, ppt, doc link inside the webview

I use Google View service to show these kind of link inside my Webview

     webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                if (isUrlCanViewByGoogle(url)) {
                    ICTEL.showLoadingDialog(context);
                }
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (isUrlCanViewByGoogle(url)) {
                    String googleDocsUrl = "http://docs.google.com/gview?embedded=true&url=";
                    if (!url.contains(googleDocsUrl)){  // To fix the bug that cannot load the file in Android 5.1
                        view.loadUrl(googleDocsUrl + url);
                    }else{
                        view.loadUrl(url);
                    }
                } else {
                    view.loadUrl(url);
                }
                return true;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                if (isUrlCanViewByGoogle(url)) {
                    ICTEL.dismissLoadingDialog();
                }
            }
        });

        webView.loadUrl(url);
     }

     public boolean isUrlCanViewByGoogle(String url) {
        if (url.endsWith(".pdf")
                || url.endsWith(".txt")
                || url.endsWith(".doc")
                || url.endsWith(".docx")
                || url.endsWith(".xls")
                || url.endsWith(".xlsx")
                || url.endsWith(".ppt")
                || url.endsWith(".pptx")
                || url.endsWith(".pages")
                || url.endsWith(".ai")
                || url.endsWith(".psd")
                || url.endsWith(".tiff")
                || url.endsWith(".dxf")
                || url.endsWith(".svg")
                || url.endsWith(".eps")
                || url.endsWith(".ps")
                || url.endsWith(".ttf")
                || url.endsWith(".xps")
                || url.endsWith(".zip")
                || url.endsWith(".rar")) {
            return true;
        } else {
            return false;
        }
    }

Want to go back to previous page when pressed back button

    @Override
    public void onBackPressed(){
        if(webView.canGoBack()){
            webView.goBack();
        }else{
            super.onBackPressed();
        }
    }

Add CSS to html file

My html file has 2 parts answer and question. I want to hide the answer part. So i do like this:

public String addCustomCss(String htmlURL) {
        InputStream is;
        try {
            is = new FileInputStream(htmlURL);
            int size = is.available();

            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();

            String str = new String(buffer);
            // Here i add the css to hide the answer part
            str = str.replace("id=\"answer_box\"", "id=\"answer_box\" style=\"display: none;\"");

            return str;
        } catch (FileNotFoundException e) {
            e.printStackTrace();            
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

And i load html file from it's converted data:

Webview wvQuestion;
String htmlData = addCustomCss(url);
wvQuestion.loadDataWithBaseURL(baseFolder, htmlData, "text/html", "UTF-8", null);

Cannot load the local html file for the first time.

In some low devices, my Webview cannot load the local html file (contains audio, image, css link) for the first time. So i cheated here that i load other url for the first time and my url in the next time.

        private boolean loadFirstTime = false;
        Webview wvQuestion;

        if (!loadFirstTime){
            wvQuestion.removeAllViews();
            wvQuestion.loadUrl("about:html");
            loadFirstTime = true;
        }
        wvQuestion.removeAllViews();
        wvQuestion.loadUrl(url);

Clone this wiki locally