android - Xamarin Android如何使用手机默认打印机功能打印从WebView打开的PDF内容

标签 android xamarin printing xamarin.android xamarin-studio

谁能帮我解决这个问题,打印 url 内容。 我在我的应用程序的 Web View 中打开 PDF 文件,然后尝试通过放置单独的打印按钮从那里打印文档。请看下面的代码。

    [Activity(Label = "PdfView")]
    public class PdfView : Activity
    {
        public static PdfView _context;
        Android.Content.Res.Resources res;
        private static string ErrorTitle, ErrorMsg;
        private static ProgressBar progressBar;

        WebView mWebView, Web_Print;
        RelativeLayout LL_Print,LL_input;
        string MyUrl;
        private WebClient _webClient = new WebClient();
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            _context = this;
            res = _context.Resources;
            SetContentView(Resource.Layout.web_pdf);
            ErrorTitle = res.GetString(Resource.String.error_title);
            ErrorMsg = res.GetString(Resource.String.Somethingwentwrong);
            progressBar = FindViewById<ProgressBar>(Resource.Id.progressBar1);
            LL_Print = FindViewById<RelativeLayout>(Resource.Id.LL_Print);
            LL_input = FindViewById<RelativeLayout>(Resource.Id.LL_input);
            Web_Print = FindViewById<WebView>(Resource.Id.Web_Print);
            Web_Print.Visibility = ViewStates.Gone;
            LL_Print.Visibility = ViewStates.Gone;
            var customWebViewClient = new WebViewLoaderClient();
            mWebView = FindViewById<WebView>(Resource.Id.Web);
            mWebView.Download += MWebview_Download;               
            mWebView.Settings.JavaScriptEnabled = true;
            mWebView.Settings.BuiltInZoomControls = true;
            mWebView.SetWebViewClient(customWebViewClient);
            mWebView.SetWebChromeClient(new WebChromeClient());
            String myPdfUrl = APIConstants.InvoicePdfUrl;
            MyUrl = "http://docs.google.com/gview?embedded=true&url=" + myPdfUrl;
            mWebView.LoadUrl(MyUrl);

            InitComonents();
        }

        private void MWebview_Download(object sender, DownloadEventArgs e)
        {
            mWebView.Visibility = ViewStates.Gone;
            LL_input.Visibility = ViewStates.Gone;
            LL_Print.Visibility = ViewStates.Visible;
            Web_Print.Visibility = ViewStates.Visible;
            var Url = e.Url;
            CustomWebViewClient client = new CustomWebViewClient(this);
            Web_Print.SetWebViewClient(client);
            Web_Print.SetWebChromeClient(new WebChromeClient());
            Web_Print.Settings.JavaScriptEnabled = true;
            Web_Print.LoadUrl(Url);
            Web_Print.Settings.UseWideViewPort = true;
            Web_Print.Settings.LoadWithOverviewMode = true;
        }


        #region // Initializing widgets
        public void InitComonents()
        {
            try
            {
                LinearLayout img_viw = FindViewById<LinearLayout>(Resource.Id.img_WV_back);
                LinearLayout img_viw_Home = FindViewById<LinearLayout>(Resource.Id.img_WV_home);

            }
            catch (Exception ex)
            {
                ex.Message.ToString();
            }
        }
        #endregion

        #region // Webview client
        public class WebViewLoaderClient : WebViewClient
        {
            public event EventHandler<bool> OnPageLoaded;
            public override bool ShouldOverrideUrlLoading(WebView view, string url)
            {
                view.LoadUrl(url);
                return true;
            }
            public override void OnPageStarted(WebView view, string url, Android.Graphics.Bitmap favicon)
            {
                base.OnPageStarted(view, url, favicon);
                progressBar.Visibility = ViewStates.Visible;
            }
            public override void OnPageFinished(WebView view, string url)
            {
                base.OnPageFinished(view, url);
                progressBar.Visibility = ViewStates.Gone;
            }
            public override void OnReceivedError(WebView view, ClientError errorCode, string description, string failingUrl)
            {
                base.OnReceivedError(view, errorCode, description, failingUrl);
                view.Visibility = ViewStates.Gone;
                Error();
            }
        }
        class MonkeyWebViewClient : WebViewClient
        {
            public override bool ShouldOverrideUrlLoading(WebView view, string url)
            {
                view.LoadUrl(url);
                return true;
            }
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
            {
                view.LoadUrl("file:///android_asset/myerrorpage.html");
            }
        }
        #endregion


        #region Error Message for Web View Error
        public static void Error()
        {
            AlertDialog.Builder alert = new AlertDialog.Builder(_context);
            alert.SetTitle(ErrorTitle);
            alert.SetMessage(ErrorMsg);
            alert.SetPositiveButton(Resource.String.ok, (senderAlert, args) =>
            {
                _context.Finish();
            });
            alert.SetCancelable(false);
            Dialog dialog = alert.Create();
            dialog.Show();
        }

        public void doWebViewPrint(string url)
        {
            PrintDocumentAdapter adapter;
            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
                adapter = mWebView.CreatePrintDocumentAdapter("test");
            else
                adapter = mWebView.CreatePrintDocumentAdapter();
            var printMgr = (PrintManager)GetSystemService(PrintService);
            printMgr.Print("printTest", adapter, null);
        }
        #endregion
    }

    public class CustomWebViewClient : WebViewClient
    {
        private PdfView myActivity;
        public bool shouldOverrideUrlLoading(WebView view, string url)
        {
            view.LoadUrl(url);
            return false;
        }
        public override void OnPageFinished(WebView view, string url)
        {
            Log.Debug("PRINT", "page finished loading " + url);
            myActivity.doWebViewPrint(url);
            //CreateWebPrintJob(view);
            base.OnPageFinished(view, url);
        }

        private void CreateWebPrintJob(WebView view)
        {
            throw new NotImplementedException();
        }

        public CustomWebViewClient(PdfView activity)
        {
            myActivity = activity;
        }
    }
}

这能够显示 PDF 的内容并打开打印机功能,但 PDF 的内容无法在打印机功能中作为预览查看,即,得到我如下 Printer Default

所以,任何人都可以帮助我解决这个问题以纠正并能够在网络上查看 PDF 内容以打印它。

最佳答案

请看下面的代码,它使打印成为可能: 这里完全改变游戏规则的是规模计算,

.
.
.
.
.
.
.
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            _context = this;
            res = _context.Resources;
            SetContentView(Resource.Layout.xxxxxxxxxxxxxxxx);
            var customWebViewClient = new WebViewLoaderClient();
            mWebView = FindViewById<WebView>(Resource.Id.Web);
            //mWebView.Download += MWebview_Download;
            UserLoginDetailList = UserInfoDBServices.getUserLoginDetailsfromDBfordroid();
            ObjLangList = UserInfoDBServices.GetCurrentLanguageListfordroid();
            mWebView.Settings.JavaScriptEnabled = true;
            mWebView.Settings.BuiltInZoomControls = true;
            mWebView.SetWebViewClient(customWebViewClient);
            String myPdfUrl = APIConstants.InvoicePdfUrl;
            MyUrl = "http://docs.google.com/gview?embedded=true&url=" + myPdfUrl;//Here in myPdfUrl variable place the url of the pdf you are getting from your server
            mWebView.LoadUrl(MyUrl);
            InitComonents();
        }
        #region // Initializing widgets
        public void InitComonents()
        {
            try
            {
                Print = FindViewById<LinearLayout>(Resource.Id.ll_TNP_Pirnt);
                Print.Visibility = ViewStates.Visible;
                Print.Click += delegate
                  {
                      LL_Print.Clickable = false;
                      var printManager = (PrintManager)GetSystemService(Context.PrintService);
                      var content = FindViewById<LinearLayout>(Resource.Id.LL_input);
                      var printAdapter = new GenericPrintAdapter(this, content);

                      printManager.Print("MyPrintJob", printAdapter, null);
                  };
            }
            catch (Exception ex)
            {
                ex.Message.ToString();
            }
        }
        #endregion
        public class GenericPrintAdapter:PrintDocumentAdapter
        {
            View view;
            Context context;
            PrintedPdfDocument document;
            float scale;
            private DownloadPdfView downloadPdfView;
            private RelativeLayout content;

            public GenericPrintAdapter(DownloadPdfView downloadPdfView, View view)
            {
                this.downloadPdfView = downloadPdfView;
                this.view = view;
            }

            public override void OnLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras)
            {
                try
                {
                    document = new PrintedPdfDocument(context, newAttributes);

                    CalculateScale(newAttributes);

                    var printInfo = new PrintDocumentInfo
                        .Builder("Invoice.pdf")
                        .SetContentType(PrintContentType.Document)
                        .SetPageCount(1)
                        .Build();

                    callback.OnLayoutFinished(printInfo, true);
                }
                catch(Exception ex)
                {
                    ex.Message.ToString();
                }

            }

            public override void OnWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback)
            {

                try
                {
                    PrintedPdfDocument.Page page = document.StartPage(0);

                    page.Canvas.Scale(scale, scale);

                    view.Draw(page.Canvas);

                    document.FinishPage(page);

                    WritePrintedPdfDoc(destination);

                    document.Close();

                    document.Dispose();

                    callback.OnWriteFinished(pages);
                }
                catch (Exception ex)
                {
                    ex.Message.ToString();
                }

            }
            void CalculateScale(PrintAttributes newAttributes)
            {
                try
                {
                    int dpi = Math.Max(newAttributes.GetResolution().HorizontalDpi, newAttributes.GetResolution().VerticalDpi);

                    int leftMargin = (int)(dpi * (float)newAttributes.MinMargins.LeftMils / 1000);
                    int rightMargin = (int)(dpi * (float)newAttributes.MinMargins.RightMils / 1000);
                    int topMargin = (int)(dpi * (float)newAttributes.MinMargins.TopMils / 1000);
                    int bottomMargin = (int)(dpi * (float)newAttributes.MinMargins.BottomMils / 1000);

                    int w = (int)(dpi * (float)newAttributes.GetMediaSize().WidthMils / 3500) - leftMargin - rightMargin;
                    int h = (int)(dpi * (float)newAttributes.GetMediaSize().HeightMils / 3500) - topMargin - bottomMargin;

                    scale = Math.Min((float)document.PageContentRect.Width() / w, (float)document.PageContentRect.Height() / h);
                }
                catch (Exception ex)
                {
                    ex.Message.ToString();
                }

            }
            void WritePrintedPdfDoc(ParcelFileDescriptor destination)
            {
                try
                {
                    var javaStream = new Java.IO.FileOutputStream(destination.FileDescriptor);
                    var osi = new OutputStreamInvoker(javaStream);
                    using (var mem = new MemoryStream())
                    {
                        document.WriteTo(mem);
                        var bytes = mem.ToArray();
                        osi.Write(bytes, 0, bytes.Length);
                    }
                }
                catch (Exception ex)
                {
                    ex.Message.ToString();
                }
            }
        }

        #region // Webview client
        public class WebViewLoaderClient : WebViewClient
        {
            public event EventHandler<bool> OnPageLoaded;
            public override bool ShouldOverrideUrlLoading(WebView view, string url)
            {
                view.LoadUrl(url);
                return true;
            }
            public override void OnPageStarted(WebView view, string url, Android.Graphics.Bitmap favicon)
            {
                base.OnPageStarted(view, url, favicon);
                progressBar.Visibility = ViewStates.Visible;
            }
            public override void OnPageFinished(WebView view, string url)
            {
                base.OnPageFinished(view, url);
                progressBar.Visibility = ViewStates.Gone;
            }
            public override void OnReceivedError(WebView view, ClientError errorCode, string description, string failingUrl)
            {
                base.OnReceivedError(view, errorCode, description, failingUrl);
                view.Visibility = ViewStates.Gone;
                Error();
            }
        }
        class MonkeyWebViewClient : WebViewClient
        {
            public override bool ShouldOverrideUrlLoading(WebView view, string url)
            {
                view.LoadUrl(url);
                return true;
            }
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
            {
                view.LoadUrl("file:///android_asset/myerrorpage.html");
            }
        }
        #endregion

        #region Error Message for Web View Error
        public static void Error()
        {
            AlertDialog.Builder alert = new AlertDialog.Builder(_context);
            alert.SetTitle(ErrorTitle);
            alert.SetMessage(ErrorMsg);
            alert.SetPositiveButton(Resource.String.ok, (senderAlert, args) =>
            {
                _context.Finish();
            });
            alert.SetCancelable(false);
            Dialog dialog = alert.Create();
            dialog.Show();
        }
        #endregion
    }
}

关于android - Xamarin Android如何使用手机默认打印机功能打印从WebView打开的PDF内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47033755/

相关文章:

java - 从 Android 4.0 降级到 Android 2.2 会产生很多问题

c# - 如何将属性绑定(bind)到 MAUI 中的 View 模型?

java - 在 JSP 中使用 try 语句时出现输出问题

javascript - 不要在表格之间分页

c# - 使用 Xamarin Forms 在 Visual Studio 中创建 Hello World 失败

python - 打印字典 (JSON) 人类可读

android - 避免多个绘图集 (hdpi/mdpi/ldpi)

android - 华为 ML Kit 文字转语音错误

android - ExpandableListView 和滚动

c# - 禁用 ToolbarItem Xamarin.Forms