Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Webview cannot render the pdf sometimes and shows blank/white page instead

  • Open the pdf in the webview using google docs
  • Open the same pdf or different pdf again and again.
  • Sometimes it will show the blank/white page in the android untill we refresh the webpage again for 1 or 2 times.

I have made the sample on the pdf. The link for the project is shown below:

https://github.com/gopalawasthi123/PdfWebView

Hope this will help you Better.

public void SetWebView(WebView webview,string externalUrl){
            webview.Tag = "webview";
            webview.Settings.JavaScriptEnabled = true;
            webview.Settings.SupportZoom ();
            webview.Settings.SetAppCacheEnabled(true);
            webview.Settings.DomStorageEnabled = true;
            webview.ZoomOut ();
            webview.ZoomIn ();
            webview.Settings.BuiltInZoomControls = true;
            webview.Settings.LoadWithOverviewMode = true;
            webview.Settings.UseWideViewPort = true;
            //webview.Settings.SetSupportZoom (true);
            webview.Settings.SetPluginState (WebSettings.PluginState.On);
            webview.Settings.GetPluginState ();
            if (externalUrl.StartsWith("http://") || externalUrl.StartsWith("https://"))
                webview.LoadUrl (externalUrl);
            webview.SetWebViewClient (new MonkeyWebViewClient (imgViewBack, imgViewForward, imgRefresh));
            webview.SetWebChromeClient (new WebChromeClient ());
        }
like image 328
Gopal Awasthi Avatar asked Apr 24 '19 11:04

Gopal Awasthi


People also ask

How can I display a PDF document into a WebView?

The very first and the easiest way of displaying the PDF file is to display it in the WebView. All you need to do is just put WebView in your layout and load the desired URL by using the webView. loadUrl() function. Now, run the application on your mobile phone and the PDF will be displayed on the screen.

Is Android WebView deprecated?

This interface was deprecated in API level 12. This interface is now obsolete.

Why is my WebView not working?

You might often face issues in updating the chrome and Android System Webview. To fix this problem, you can reboot your device, check your internet connection, stop auto-updating all apps, clear Google Playstore cache, and storage, leave the beta testing program, and manually update Android WebView app from Playstore.

What is the WebView layout on Android?

The WebView class is an extension of Android's View class that allows you to display web pages as a part of your activity layout. It does not include any features of a fully developed web browser, such as navigation controls or an address bar. All that WebView does, by default, is show a web page.


5 Answers

You can reload the page until it displays the pdf in this way:

public void onPageFinished(WebView view, String url) {
if (view.getTitle().equals(""))
    view.reload();
}
like image 154
Michelangelo Pucci Avatar answered Oct 23 '22 11:10

Michelangelo Pucci


After testing second PDF URL file, WebView seems like that can not load large PDF file.

Reason:

WebView display HTML. The fact that this works at all is by a hack- google will convert simple PDFs into HTML. It doesn't seem like they support anything that big. Even if they did, I would expect loading a large page PDF converted to HTML would be so large I highly doubt you'd be able to load it without going OOM. Use an appropriate PDF library, make a real PDF rendering view, and make sure not to render more of the PDF at a time than you need (or else you'll go OOM anyway). In other words, don't rely on hacky solutions you never should have relied on in the first place.

Solution:

You should try alternatives like PDF.js running locally in your device, instead of a service like Google Docs preview.(Or download PDF first to local file path)

Put it in your assets folder and tweak the example:

wv.loadUrl("file:///android_asset/web/viewer.html");

Also, you can have Out Of Memory situations. An alternative to try is a native viewer like AndroidPdfViewer.

like image 33
Junior Jiang Avatar answered Oct 23 '22 12:10

Junior Jiang


We can solve the Problem in the two ways. 1. One is to use the Js.Pdf Plugin on the server end. It surely solve the problem but if we have multiple pdf's in the Fragment then it may cause the out of memory situations and app can crash. 2. Second option is we can recursively called the function to load webview. This will also cause the issue but with less frequency Below is the code:

private void showPdf(final String imageString) {
pdfView.invalidate();
pdfView.getSettings().setJavaScriptEnabled(true);
pdfView.getSettings().setSupportZoom(true);
pdfView.loadUrl("http://docs.google.com/gview?embedded=true&url=" + imageString);
pdfView.setWebViewClient(new WebViewClient() {
    boolean checkhasOnPageStarted = false;

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        checkhasOnPageStarted = true;
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        if (checkhasOnPageStarted ) {
            pdfView.loadUrl(removePdfTopIcon);
        } else {
            showPdf(imageString);
        }
    }
});
}
like image 33
Gopal Awasthi Avatar answered Oct 23 '22 13:10

Gopal Awasthi


I was having the exact same issue and found that there was always a chance the WebView would not load on the first load attempt, especially if the pdf was on the larger side. The code I put together below works 100% of the time. From my beginner's understanding, it safely utilizes a separate thread to loop through and test the load status of the WebView, re-attempting a load of the view until successful. As this question was posted a year ago, I have generalized my solution to best benefit new viewers.

public class WebViewActivity extends AppCompatActivity {

String PDFView;
WebView webView;
String PDFBrowserView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //Get the intended "PDFView"
    PDFView = getIntent().getExtras().get("PDFView").toString();
    //Have to manually encode (?) the url to display it
    try {
        PDFView = URLEncoder.encode(PDFView, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    //Full display url
    PDFBrowserView = "https://docs.google.com/gview?embedded=true&url=" + PDFView;

    //Initialize a new "WebView" instance
    webView = new WebView(WebViewActivity.this);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setAllowFileAccessFromFileURLs(true);
    webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
    webView.getSettings().setBuiltInZoomControls(true);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setPluginState(WebSettings.PluginState.ON);
    webView.getSettings().setDomStorageEnabled(true);
    webView.getSettings().setLoadWithOverviewMode(true);
    webView.getSettings().setUseWideViewPort(true);
    //This handles callbacks (?)
    webView.setWebChromeClient(new WebChromeClient());

    //Call this to load page if page is blank with pdf url until page is not blank
    checkPageFinished();
}

public void checkPageFinished() {
    //If view is blank:
    if (webView.getContentHeight() == 0) {

        //Run off main thread to control delay
        webView.postDelayed(new Runnable() {
            @Override
            public void run() {
                //Load url into the "WebView"
                webView.loadUrl(PDFBrowserView);
            }
            //Set 1s delay to give the view a longer chance to load before 
            // setting the view (or more likely to display blank)
        }, 1000);
        //Set the view with the selected pdf
        setContentView(webView);

        webView.postDelayed(new Runnable() {
            @Override
            public void run() {
                //If view is still blank:
                if (webView.getContentHeight() == 0) {
                    //Loop until it works
                    checkPageFinished();
                }
            }
            //Safely loop this function after 1.5s delay if page is not loaded
        }, 1500);

        }
    }
}
like image 34
Michael Plischke Avatar answered Oct 23 '22 12:10

Michael Plischke


There are some ways through which we can identify whether a Page/URL is loaded properly or not from onPageFinished() method of the Webview and based on that reload() url.

Option 1 : To check with contentHeight of the webview.

override fun onPageFinished(view: WebView?, url: String?) {
    if(view?.contentHeight == 0){
        view?.reload()
        return
    }
    super.onPageFinished(view, url)
}
    

Option 2 : To check with title of the webview.

override fun onPageFinished(view: WebView?, url: String?) {
    if(view?.title.isNullOrEmpty()){
        view?.reload()
        return
    }
    super.onPageFinished(view, url)
}
like image 38
Nikunj Avatar answered Oct 23 '22 11:10

Nikunj