Android WebView:用 PDF 显示网站

Posted

技术标签:

【中文标题】Android WebView:用 PDF 显示网站【英文标题】:Android WebView: Display Website with PDF 【发布时间】:2019-03-24 08:27:21 【问题描述】:

在我的 Xamarin.android 应用中,我使用 WebView 来显示网站:

AXML:

<LinearLayout
        android:id="@+id/auditStructurUseCaseLinearLayout"
        android:layout_
        android:layout_
        android:layout_weight="1">
        <WebView
            android:id="@+id/auditWebview"
            android:layout_
            android:layout_ />
    </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;
    

这适用于普通网站。我可以在网站内导航,并且可以像使用普通浏览器一样使用它。

问题: 我想显示嵌入网站的 PDF。今天的浏览器带有 PDF 插件来显示 PDF,所以问题是,是否有一种用于 WebView 的 PDF 插件,或者我是否缺少在网站内显示 PDF 的一些设置?

如果我尝试使用 PDF 打开网站,网站会要求使用 PDF 查看器。

翻译很遗憾,由于您没有 PDF 查看器,因此无法显示 PDF。您可以在此处下载 PDF。

很遗憾,下载按钮也不起作用。

或者也许有人有另一种方法,它不使用 WebView。

编辑:

我尝试使用_webview.SetWebChromeClient(new WebChromeClient());,但这会打开 Chrome 应用程序。所以我尝试使用WebViewClientChromeViewClient,就像this 问题中建议的那样。

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

但这会导致与描述相同的问题。

【问题讨论】:

尝试设置WebChromeClient 如果我使用setWebChromeClient,则 URL 在 Chrome 中打开,而不是在 WebView 中。您可以使用webSettings.SetSupportMultipleWindows(true) 并同时设置WebChromeClientWebViewClient,但这会导致我同样的问题 ***.com/a/24942468/779051 您找到解决方案了吗?我坚持下去。帮帮我:D 【参考方案1】:

你可以像这样使用谷歌文档

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);

请参考问题here。

现在您还将拥有除 pdf 之外的内容,并且可能在您的站点中的某处有指向 pdf 的链接。在这种情况下,您可以将此方法放在 shouldOverrideLoadingUrl() 方法中。

根据评论编辑

    下载html 使用 iframe 更改包含对 pdf 的引用的行 - 在 iframe 中加载谷歌文档 尝试使用 loadDataWithBaseURL() 代替 webview.loadUrl()。 - 如果您想了解更多关于如何使用 loadDataWithBaseUrl() 的信息,请参考this answer。

【讨论】:

感谢您的回答,但您没有得到我的问题。我不想在 web 视图中显示单个 PDF 文档(我知道您的解决方案)。我想用嵌入的 pdf 显示整个网站。如果你看我的截图,棕色条之间的整个区域就是网站。 好的。我得到了它。在这种情况下,您可以尝试下载 html,然后使用 以编程方式将带有 ref 的行更改为 pdf 目前我正在使用shouldOverrideLoadingUrl() 来确定 URL 是否包含“.pdf”(这样我可以抓住“您可以在此处下载 pdf”按钮)并显示 pdf 分隔从网络视图。但我想看到我的网站嵌入了 PDF 请尝试更新的解决方案。在你的 shouldOverrideLoadingUrl() 中应用它。 我无法让它工作,你有一些代码示例吗?【参考方案2】:

输入你的网址,

url = "https://drive.google.com/viewerng/viewer?embedded=true&url=" + GetString(Resource.String.your_pdf_url);

【讨论】:

【参考方案3】:

使用此代码打开网页视图,然后我制作了一个浮动操作按钮,点击它,您可以下载 pdf 视图...确保输入正确的 URL

但首先..创建另一个名为 PDFVIEW 的类,我们将在我们的代码中使用这个类方法...

类 PDF 查看代码...

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();
    


//现在主类代码..

@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());
            
        
    );

【讨论】:

以上是关于Android WebView:用 PDF 显示网站的主要内容,如果未能解决你的问题,请参考以下文章

Android - 如何在 webview 中显示 .js 文件中的 pdf 内容

如何显示包含 pdf 的 url 并将其显示在 Webview Android Java 中

加载时在webview中显示白页(PDF url)url android

在android的Webview中加载sdcard pdf文件

Android Web 视图不显示 PDF

关于Android中WebView在加载网页的时候,怎样应用本地的CSS效果