1

In my Xamarin.Android App I am using a WebView to display a website:

AXML:

<LinearLayout
        android:id="@+id/auditStructurUseCaseLinearLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1">
        <WebView
            android:id="@+id/auditWebview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

Fragment.cs:

    _webview.SetWebViewClient(new ExtendWebViewClient());
    WebSettings webSettings = _webview.Settings;
    webSettings.JavaScriptEnabled = true;
    webSettings.DisplayZoomControls = false;
    webSettings.BuiltInZoomControls = true;
    _webview.LoadUrl(URL);

ExtendWebViewClient:

internal class ExtendWebViewClient : WebViewClient
{
    public override bool ShouldOverrideUrlLoading(WebView view, string url)
    {
        view.LoadUrl(url);
        return true;
    }
}

This works well for normal websites. I can navigate inside awebsite and can use it like a normal browser.

Problem: I want to display PDFs which are embedded inside a website. Today's browser come with PDF Plugins to display PDF, so the question is, is there a kind of PDF Plugin for the WebView or am I missing some settings to display a PDF inside a Website?

If I try to open websites with PDF, the website asks for a PDF-Viewer.

Translation: Unfortunately, the PDF can not be displayed because you do not have a PDF viewer. You can download the PDF here. enter image description here

Unfortunately, the download-button is functionless aswell.

Or maybe someone has another approach which does not use a WebView.

EDIT:

I tried using _webview.SetWebChromeClient(new WebChromeClient()); but this opens the the Chrome App. So I tried to use WebViewClient and ChromeViewClient like suggested in this question.

WebSettings webSettings = _webview.Settings;
            webSettings.JavaScriptEnabled = true;
            webSettings.DisplayZoomControls = false;
            webSettings.BuiltInZoomControls = true;
            webSettings.SetSupportMultipleWindows(true);
            _webview.SetWebChromeClient(new WebChromeClient());
            _webview.SetWebViewClient(new ExtendWebViewClient());

But this leads to the same problem as described.

Aiko West
  • 791
  • 1
  • 10
  • 30

3 Answers3

0

Put your URL like,

url = "https://drive.google.com/viewerng/viewer?embedded=true&url=" + GetString(Resource.String.your_pdf_url);
Sagar Zala
  • 4,854
  • 9
  • 34
  • 62
Anand
  • 1,866
  • 3
  • 26
  • 49
0

You can use google docs like this

WebView webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true); 
String pdf = "url_to_your_pdf" ;
webview.loadUrl("http://drive.google.com/viewerng/viewer?embedded=true&url=" + pdf);

Please refer to the question here.

Now you will also have contents other than pdf and probably a link to pdf somewhere in your site. in that case you can put this method inside shouldOverrideLoadingUrl() method.

Edited based on Comment

  1. Download html
  2. change the line containing reference to pdf with iframe - load google docs inside an iframe
  3. instead of webview.loadUrl() try loadDataWithBaseURL(). - please refer to this answer if you want more information about how to use loadDataWithBaseUrl().
Mayank Kumar Chaudhari
  • 16,027
  • 10
  • 55
  • 122
  • thanks for your answer, but you did not get my problem. I do not want to display a single PDF docuemnt in a webview (your solution is known to me). I want to display the whole website with the embedded pdf. If you look on my screenshot, the whole area between the brown bars is the website. – Aiko West Oct 25 '18 at 05:34
  • ok. I got it. In that case you may try downloading html, then programmatically change the line with ref to pdf with – Mayank Kumar Chaudhari Oct 25 '18 at 05:37
  • at the moment I am using `shouldOverrideLoadingUrl()` to determine, if the URL contains ".pdf" (this way i can catch the "you can download the pdf here" button) and display the pdf seperated from the webview. But I want to see my website with the embedded PDF – Aiko West Oct 25 '18 at 05:38
  • please try updated solution. Apply this inside your shouldOverrideLoadingUrl(). – Mayank Kumar Chaudhari Oct 25 '18 at 05:43
  • i could not manage to get that working, do you have some code examples? – Aiko West Oct 26 '18 at 06:19
0

Use this code to open web view and then i have made a Floating Action Button and on the click of it, you can download the pdf view...Make Sure you enter correct URL's

BUT FIRST..MAKE ANOTHER CLASS NAMED PDFVIEW AND WE WILL USE THIS CLASS METHOD'S IN OUR CODE...

CLASS PDFVIEW CODE...

public class PdfView {

private static final int REQUEST_CODE=101;

/**
 * convert webview content into to pdf file
 * @param activity pass the current activity context
 * @param webView webview
 * @param directory directory path where pdf file will be saved
 * @param fileName name of the pdf file.
 * */
public static void createWebPrintJob(Activity activity, WebView webView, File directory, String fileName, final Callback callback) {

    //check the marshmallow permission
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
            callback.failure();
           return;
        }
    }

    String jobName = activity.getString(R.string.app_name) + " Document";
    PrintAttributes attributes = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        attributes = new PrintAttributes.Builder()
                .setMediaSize(PrintAttributes.MediaSize.ISO_A3)
                .setResolution(new PrintAttributes.Resolution("pdf", "pdf", 600, 600))
                .setMinMargins(PrintAttributes.Margins.NO_MARGINS).build();
    }
    PdfPrint pdfPrint = new PdfPrint(attributes);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        pdfPrint.print(webView.createPrintDocumentAdapter(jobName), directory, fileName, new PdfPrint.CallbackPrint() {
            @Override
            public void success(String path) {
                callback.success(path);
            }

            @Override
            public void onFailure() {
                callback.failure();
            }
        });
    }else {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            pdfPrint.print(webView.createPrintDocumentAdapter(), directory, fileName, new PdfPrint.CallbackPrint() {
                @Override
                public void success(String path) {
                    callback.success(path);
                }

                @Override
                public void onFailure() {
                    callback.failure();
                }
            });
        }
    }
}


/**
 * create alert dialog to open the pdf file
 * @param activity pass the current activity context
 * @param title  to show the heading of the alert dialog
 * @param message  to show on the message area.
 * @param path file path create on storage directory
 */
public static void openPdfFile(final Activity activity, String title, String message, final String path){

    //check the marshmallow permission
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
            return;
        }
    }

    AlertDialog.Builder builder=new AlertDialog.Builder(activity);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.setPositiveButton("Open", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
            fileChooser(activity,path);
        }
    });

    builder.setNegativeButton("Dismiss", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
        }
    });

    AlertDialog alert = builder.create();
    alert.show();

}

/** callback interface to get the result back after created pdf file*/
public interface Callback{
    void success(String path);
    void failure();
}


/**
 * @param activity pass the current activity context
 * @param path storage full path
 */
private  static void fileChooser(Activity activity, String path) {
    File file = new File(path);
    Intent target = new Intent("android.intent.action.VIEW");
    //Uri uri = FileProvider.getUriForFile(activity, "${applicationId}.com.package.name.fileprovider", file);
    Uri uri = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName()+ ".fileprovider", file);
    target.setDataAndType(uri, "application/pdf");
    target.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    Intent intent = Intent.createChooser(target, "Open File");
    try {
        activity.startActivity(intent);
    } catch (ActivityNotFoundException var6) {
        var6.printStackTrace();
    }

}

}

//NOW MAIN CLASS CODE..

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my_orders);

    mToolbar = (Toolbar) findViewById(R.id.toolbar);
    WebView wb = (WebView) findViewById(R.id.webview);

    wb.getSettings().setBuiltInZoomControls(true);


    Pbar = (ProgressBar) findViewById(R.id.pB1);


        WebSettings ws = wb.getSettings();
        ws.setJavaScriptEnabled(true);
        ws.setDomStorageEnabled(true);
        ws.setAllowFileAccess(true);
        wb.getSettings().setBuiltInZoomControls(true);
        //   wb.getSettings().setDisplayZoomControls(false);
        wb.clearCache(true);

    wb.setWebChromeClient(new WebChromeClient() {

        public void onProgressChanged(WebView view, int progress) {
            if (progress < 100 && Pbar.getVisibility() == ProgressBar.GONE) {
                Pbar.setVisibility(ProgressBar.VISIBLE);
            }
            Pbar.setProgress(progress);
            if (progress == 100) {
                Pbar.setVisibility(ProgressBar.GONE);
                pdfdownload.setVisibility(View.VISIBLE);
            }
        }

    });

    pdfdownload = (FloatingActionButton) findViewById(R.id.pdf);

    pdfdownload = (FloatingActionButton) findViewById(R.id.pdf);
    pdfdownload.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM + "/ANY_DIRECTORY/");

            final ProgressDialog progressDialog = new ProgressDialog(context);
            progressDialog.setMessage("Please wait");
            progressDialog.show();

            //PDFView Class Method
            PdfView.createWebPrintJob(context, wb, path, fileName, new PdfView.Callback() {

                @Override
                public void success(String path) {
                    progressDialog.dismiss();
                    PdfView.openPdfFile(context.this, getString(R.string.app_name), "Do you want to open the pdf file?" + fileName, path);
                }

                @Override
                public void failure() {
                    progressDialog.dismiss();

                }
            });

        }
    });

    wb.setWebViewClient(new WebViewClient() {
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // do your handling codes here, which url is the requested url
            // probably you need to open that url rather than redirect:
            Log.e("redirectUrl", "" + url);


       //CHECK YOUR URL CONDITIONS TO OPEN RIGHT URL FOR PDF, IF ANY..OTHERWISE LOAD DIRECTLY
    if (url.contains("/guest/home")) {
                view.loadUrl(postUrl);
            } else {
                view.loadUrl(url);
            }

            return false; // then it is not handled by default action
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            Log.e("url finished", url);
                        }
    });

    wb.setDownloadListener(new DownloadListener() {
        public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
            Log.e("DOWNLOAD", url + " , " + userAgent + " , " + contentDisposition + " , " + mimetype + " , " + contentLength);
            try {
                DownloadManager.Request request = new DownloadManager.Request(Uri.parse(newURL[1].trim()));
                request.allowScanningByMediaScanner();
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //Notify client once download is completed!
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, file_name);
                DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                dm.enqueue(request);
                Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                Log.e("download", "download fail" + e.toString());
            }
        }
    });

}

Ashmeet Arora
  • 164
  • 1
  • 3
  • 11