Android - Load PDF inside webview

前端 未结 5 1077
暖寄归人
暖寄归人 2020-12-28 11:11

I have this webview code and I want to make it possible to have the PDF files opened when a user clicks on a PDF link. Here is the code, can you tell me what I have to put

相关标签:
5条回答
  • 2020-12-28 11:42

    This could be as simple as:

    try
    {
     Intent intentUrl = new Intent(Intent.ACTION_VIEW);
     intentUrl.setDataAndType(url, "application/pdf");
     intentUrl.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
     myActivity.startActivity(intentUrl);
    }
    catch (ActivityNotFoundException e)
    {
     Toast.makeText(myActivity, "No PDF Viewer Installed", Toast.LENGTH_LONG).show();
    }
    

    though I've not tried this.

    In our apps, we DOWNLOAD the PDF to the apps file system, make it world readable, then pass the path in an Intent to open a PDF viewing app (e.g. Acrobat Reader). Please note that you'd also need to also be concerned with cleaning up these downloaded PDF's!

    in your try block put

    new DownloadPDFTask().execute(url);
    

    DownloadPDFTask class:

    public class DownloadPDFTask extends AsyncTask<String, Void, Integer> 
    {
        protected ProgressDialog mWorkingDialog;    // progress dialog
        protected String mFileName;         // downloaded file
        protected String mError;            // for errors
    
        @Override
        protected Integer doInBackground(String... urls)
        {
    
         try
         {
          byte[] dataBuffer = new byte[4096];
              int nRead = 0;
    
              // set local filename to last part of URL
              String[] strURLParts = urls[0].split("/");
              if (strURLParts.length > 0)
                mFileName = strURLParts[strURLParts.length - 1];
              else
                    mFileName = "REPORT.pdf";
    
              // download URL and store to strFileName
    
              // connection to url
          java.net.URL urlReport = new java.net.URL(urls[0]);
              URLConnection urlConn = urlReport.openConnection();
              InputStream streamInput = urlConn.getInputStream();
              BufferedInputStream bufferedStreamInput = new BufferedInputStream(streamInput);
              FileOutputStream outputStream = myActivity.openFileOutput(mFileName,Context.MODE_WORLD_READABLE); // must be world readable so external Intent can open!
              while ((nRead = bufferedStreamInput.read(dataBuffer)) > 0)
                    outputStream.write(dataBuffer, 0, nRead);
              streamInput.close();
              outputStream.close();
          }
          catch (Exception e)
          {
           Log.e("myApp", e.getMessage());
           mError = e.getMessage();
           return (1);
          }
    
         return (0);
        }
    
        //-------------------------------------------------------------------------
        // PreExecute - UI thread setup
        //-------------------------------------------------------------------------
    
        @Override
        protected void onPreExecute()
        {
         // show "Downloading, Please Wait" dialog
         mWorkingDialog = ProgressDialog.show(myActivity, "", "Downloading PDF Document, Please Wait...", true);
         return;
        }
    
        //-------------------------------------------------------------------------
        // PostExecute - UI thread finish
        //-------------------------------------------------------------------------
    
        @Override
        protected void onPostExecute (Integer result)
        {
             if (mWorkingDialog != null)
          {
           mWorkingDialog.dismiss();
           mWorkingDialog = null;
          }
    
             switch (result)
             {
             case 0:                            // a URL
    
                // Intent to view download PDF
                Uri uri  = Uri.fromFile(myActivity.getFileStreamPath(mFileName));
    
                try
                {
                    Intent intentUrl = new Intent(Intent.ACTION_VIEW);
                    intentUrl.setDataAndType(uri, "application/pdf");
                    intentUrl.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    myActivity.startActivity(intentUrl);
                }
                catch (ActivityNotFoundException e)
                {
                    Toast.makeText(myActivity, "No PDF Viewer Installed", Toast.LENGTH_LONG).show();
                }
    
                break;
    
            case 1:                         // Error
    
                Toast.makeText(myActivity, mError, Toast.LENGTH_LONG).show();
                break;
    
            }
    
        }
    
    }
    

    any reference to "myActivity" must be replaced with a reference to your Activity class

    0 讨论(0)
  • 2020-12-28 11:59

    I was trying to handle this exact same scenario. The solution I came up with is below.

    public boolean shouldOverrideUrlLoading(WebView view, String url) {
                String cleanUrl = url;
                if (url.contains("?")) {
                    // remove the query string
                    cleanUrl = url.substring(0,url.indexOf("?"));
                }
    
                if (cleanUrl.endsWith("pdf")) {
    
                    try {
                        Uri uriUrl = Uri.parse(cleanUrl);
                        Intent intentUrl = new Intent(Intent.ACTION_VIEW, uriUrl);
                        startActivity(intentUrl);
                        return true;
    
                    } catch (Exception e) {
                        System.out.println(e);
                        Toast.makeText(context,"No PDF Viewer Installed", Toast.LENGTH_LONG).show();
                    }
                }
    
                return false;
            }
    

    I needed to make sure it would handle pdf links, even if there was a query string. Still a bit hacky as the cleanUrl needs to end in "pdf", but so long as that is true, this should work. If you're serving up pdf's through a php script or something, you might want to dig a little deeper, handle things based on MIME type or something.

    0 讨论(0)
  • 2020-12-28 11:59

    FWIW, mozilla has a PDF-reader-entirely-in-JavaScript that's apache licensed. Might be worth looking into if you don't mind the extra size. That way you can do everything in-browser and won't have to rely on a 3rd party PDF reader.

    0 讨论(0)
  • 2020-12-28 12:05

    Please checkout the example for handling redirect urls and open PDF without download, in webview.

    private void init()
    {
        WebView webview = (WebView) findViewById(R.id.webview);
        WebSettings settings = webview.getSettings();
        settings.setJavaScriptEnabled(true);
        webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
    
        PdfWebViewClient pdfWebViewClient = new PdfWebViewClient(this, webview);
        pdfWebViewClient.loadPdfUrl(
                    "https://www.google.co.in/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwjgwIfp3KXSAhXrhFQKHQqEDHYQFggZMAA&url=http%3A%2F%2Fwww.orimi.com%2Fpdf-test.pdf&usg=AFQjCNERYYcSfMLS5ukBcT2Qy11YxEhXqw&cad=rja");
    }
    
    private class PdfWebViewClient extends WebViewClient
    {
        private static final String TAG = "PdfWebViewClient";
        private static final String PDF_EXTENSION = ".pdf";
        private static final String PDF_VIEWER_URL = "http://docs.google.com/gview?embedded=true&url=";
    
        private Context mContext;
        private WebView mWebView;
        private ProgressDialog mProgressDialog;
        private boolean isLoadingPdfUrl;
    
        public PdfWebViewClient(Context context, WebView webView)
        {
            mContext = context;
            mWebView = webView;
            mWebView.setWebViewClient(this);
        }
    
        public void loadPdfUrl(String url)
        {
            mWebView.stopLoading();
    
            if (!TextUtils.isEmpty(url))
            {
                isLoadingPdfUrl = isPdfUrl(url);
                if (isLoadingPdfUrl)
                {
                    mWebView.clearHistory();
                }
    
                showProgressDialog();
            }
    
            mWebView.loadUrl(url);
        }
    
        @SuppressWarnings("deprecation")
        @Override
        public boolean shouldOverrideUrlLoading(WebView webView, String url)
        {
            return shouldOverrideUrlLoading(url);
        }
    
        @SuppressWarnings("deprecation")
        @Override
        public void onReceivedError(WebView webView, int errorCode, String description, String failingUrl)
        {
            handleError(errorCode, description.toString(), failingUrl);
        }
    
        @TargetApi(Build.VERSION_CODES.N)
        @Override
        public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request)
        {
            final Uri uri = request.getUrl();
            return shouldOverrideUrlLoading(webView, uri.toString());
        }
    
        @TargetApi(Build.VERSION_CODES.N)
        @Override
        public void onReceivedError(final WebView webView, final WebResourceRequest request, final WebResourceError error)
        {
            final Uri uri = request.getUrl();
            handleError(error.getErrorCode(), error.getDescription().toString(), uri.toString());
        }
    
        @Override
        public void onPageFinished(final WebView view, final String url)
        {
            Log.i(TAG, "Finished loading. URL : " + url);
            dismissProgressDialog();
        }
    
        private boolean shouldOverrideUrlLoading(final String url)
        {
            Log.i(TAG, "shouldOverrideUrlLoading() URL : " + url);
    
            if (!isLoadingPdfUrl && isPdfUrl(url))
            {
                mWebView.stopLoading();
    
                final String pdfUrl = PDF_VIEWER_URL + url;
    
                new Handler().postDelayed(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        loadPdfUrl(pdfUrl);
                    }
                }, 300);
    
                return true;
            }
    
            return false; // Load url in the webView itself
        }
    
        private void handleError(final int errorCode, final String description, final String failingUrl)
        {
            Log.e(TAG, "Error : " + errorCode + ", " + description + " URL : " + failingUrl);
        }
    
        private void showProgressDialog()
        {
            dismissProgressDialog();
            mProgressDialog = ProgressDialog.show(mContext, "", "Loading...");
        }
    
        private void dismissProgressDialog()
        {
            if (mProgressDialog != null && mProgressDialog.isShowing())
            {
                mProgressDialog.dismiss();
                mProgressDialog = null;
            }
        }
    
        private boolean isPdfUrl(String url)
        {
            if (!TextUtils.isEmpty(url))
            {
                url = url.trim();
                int lastIndex = url.toLowerCase().lastIndexOf(PDF_EXTENSION);
                if (lastIndex != -1)
                {
                    return url.substring(lastIndex).equalsIgnoreCase(PDF_EXTENSION);
                }
            }
            return false;
        }
    }
    
    0 讨论(0)
  • 2020-12-28 12:05

    Loading pdf within a webview:

    WebView wv = (WebView) view.findViewById(R.id.webPage);
                wv.getSettings().setJavaScriptEnabled(true);
                wv.setWebViewClient(new WebClient());
                wv.loadUrl("http://drive.google.com/viewerng/viewer?embedded=true&url=" + mUrl);
                wv.getSettings().setBuiltInZoomControls(true);
    

    mUrl - will be your pdf link

    0 讨论(0)
提交回复
热议问题