Để in nội dung không chỉ là một bức ảnh đơn giản trên Android, bạn cần phải soạn văn bản và hình ảnh đồ hoạ trong một tài liệu in. Khung Android cung cấp một cách sử dụng HTML để soạn tài liệu và in tài liệu đó bằng mã tối thiểu.
Trong Android 4.4 (API cấp 19), lớp WebView
đã được cập nhật để cho phép in nội dung HTML. Lớp này cho phép bạn tải một tài nguyên HTML cục bộ hoặc tải một trang xuống từ web, tạo một lệnh in và chuyển lệnh đó cho các dịch vụ in của Android.
Bài học này sẽ hướng dẫn bạn cách tạo nhanh một tài liệu HTML chứa văn bản và đồ hoạ, đồng thời sử dụng WebView
để in tài liệu đó.
Tải tài liệu HTML
In tài liệu HTML bằng WebView
bao gồm việc tải tài nguyên HTML hoặc tạo tài liệu HTML dưới dạng một chuỗi. Phần này mô tả cách tạo một chuỗi HTML và tải chuỗi đó vào WebView
để in.
Đối tượng khung hiển thị này thường được dùng như một phần của bố cục hoạt động. Tuy nhiên, nếu ứng dụng của bạn không sử dụng WebView
, thì bạn có thể tạo một thực thể của lớp dành riêng cho mục đích in. Các bước chính để tạo chế độ xem bản in tuỳ chỉnh này là:
- Tạo một
WebViewClient
bắt đầu lệnh in sau khi tài nguyên HTML được tải. - Tải tài nguyên HTML vào đối tượng
WebView
.
Mã mẫu sau đây minh hoạ cách tạo một WebViewClient
đơn giản và tải nhanh một tài liệu HTML được tạo:
Kotlin
private var mWebView: WebView? = null private fun doWebViewPrint() { // Create a WebView object specifically for printing val webView = WebView(activity) webView.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) = false override fun onPageFinished(view: WebView, url: String) { Log.i(TAG, "page finished loading $url") createWebPrintJob(view) mWebView = null } } // Generate an HTML document on the fly: val htmlDocument = "<html><body><h1>Test Content</h1><p>Testing, testing, testing...</p></body></html>" webView.loadDataWithBaseURL(null, htmlDocument, "text/HTML", "UTF-8", null) // Keep a reference to WebView object until you pass the PrintDocumentAdapter // to the PrintManager mWebView = webView }
Java
private WebView mWebView; private void doWebViewPrint() { // Create a WebView object specifically for printing WebView webView = new WebView(getActivity()); webView.setWebViewClient(new WebViewClient() { public boolean shouldOverrideUrlLoading(WebView view, String url) { return false; } @Override public void onPageFinished(WebView view, String url) { Log.i(TAG, "page finished loading " + url); createWebPrintJob(view); mWebView = null; } }); // Generate an HTML document on the fly: String htmlDocument = "<html><body><h1>Test Content</h1><p>Testing, " + "testing, testing...</p></body></html>"; webView.loadDataWithBaseURL(null, htmlDocument, "text/HTML", "UTF-8", null); // Keep a reference to WebView object until you pass the PrintDocumentAdapter // to the PrintManager mWebView = webView; }
Lưu ý: Hãy đảm bảo rằng lệnh gọi để tạo lệnh in diễn ra trong phương thức onPageFinished()
của WebViewClient
mà bạn đã tạo ở phần trước. Nếu bạn chỉ đợi đến khi tải trang xong, thì bản in ra có thể chưa hoàn chỉnh hoặc bị trống, hoặc có thể bị lỗi hoàn toàn.
Lưu ý: Mã ví dụ ở trên lưu giữ một thực thể của đối tượng WebView
để không thu thập rác trước khi tạo lệnh in. Hãy nhớ làm như vậy trong quá trình triển khai của riêng bạn, nếu không thì quá trình in có thể không thành công.
Nếu bạn muốn đưa hình ảnh đồ hoạ vào trang, hãy đặt tệp đồ hoạ vào thư mục assets/
của dự án và chỉ định một URL cơ sở trong tham số đầu tiên của phương thức loadDataWithBaseURL()
, như trong đoạn mã ví dụ sau:
Kotlin
webView.loadDataWithBaseURL( "file:///android_asset/images/", htmlBody, "text/HTML", "UTF-8", null )
Java
webView.loadDataWithBaseURL("file:///android_asset/images/", htmlBody, "text/HTML", "UTF-8", null);
Bạn cũng có thể tải một trang web để in bằng cách thay thế phương thức loadDataWithBaseURL()
bằng loadUrl()
như minh hoạ dưới đây.
Kotlin
webView.loadUrl("https://developer.android.com/about/index.html")
Java
// Print an existing web page (remember to request INTERNET permission!): webView.loadUrl("https://developer.android.com/about/index.html");
Khi sử dụng WebView
để tạo tài liệu in, bạn nên lưu ý các hạn chế sau:
- Bạn không thể thêm đầu trang hoặc chân trang, bao gồm cả số trang, vào tài liệu.
- Các tuỳ chọn in cho tài liệu HTML không bao gồm các tuỳ chọn in phạm vi trang, ví dụ: Không hỗ trợ in trang 2 đến 4 của tài liệu HTML gồm 10 trang.
- Mỗi thực thể của
WebView
chỉ có thể xử lý một lệnh in tại mỗi thời điểm. - Tài liệu HTML có chứa các thuộc tính in của CSS, chẳng hạn như các thuộc tính ngang, không được hỗ trợ.
- Bạn không thể sử dụng JavaScript trong tài liệu HTML để kích hoạt tính năng in.
Lưu ý: Nội dung của đối tượng WebView
có trong một bố cục cũng có thể được in sau khi tải tài liệu.
Nếu bạn muốn tạo một bản in đầu ra tuỳ chỉnh hơn và có toàn quyền kiểm soát nội dung được vẽ trên trang được in, hãy chuyển đến bài học tiếp theo: Bài học In tài liệu tuỳ chỉnh.
Tạo lệnh in
Sau khi tạo WebView
và tải nội dung HTML, ứng dụng của bạn gần như đã hoàn tất một phần của quá trình in. Các bước tiếp theo là truy cập vào PrintManager
, tạo bộ chuyển đổi in và cuối cùng là tạo một lệnh in. Ví dụ sau minh hoạ cách thực hiện các bước này:
Kotlin
private fun createWebPrintJob(webView: WebView) { // Get a PrintManager instance (activity?.getSystemService(Context.PRINT_SERVICE) as? PrintManager)?.let { printManager -> val jobName = "${getString(R.string.app_name)} Document" // Get a print adapter instance val printAdapter = webView.createPrintDocumentAdapter(jobName) // Create a print job with name and adapter instance printManager.print( jobName, printAdapter, PrintAttributes.Builder().build() ).also { printJob -> // Save the job object for later status checking printJobs += printJob } } }
Java
private void createWebPrintJob(WebView webView) { // Get a PrintManager instance PrintManager printManager = (PrintManager) getActivity() .getSystemService(Context.PRINT_SERVICE); String jobName = getString(R.string.app_name) + " Document"; // Get a print adapter instance PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(jobName); // Create a print job with name and adapter instance PrintJob printJob = printManager.print(jobName, printAdapter, new PrintAttributes.Builder().build()); // Save the job object for later status checking printJobs.add(printJob); }
Ví dụ này lưu một thực thể của đối tượng PrintJob
để ứng dụng dùng (không bắt buộc). Ứng dụng của bạn có thể sử dụng đối tượng này để theo dõi tiến trình của lệnh in trong quá trình xử lý. Phương pháp này hữu ích khi bạn muốn theo dõi trạng thái của lệnh in trong ứng dụng để hoàn tất, không thành công hoặc khi người dùng huỷ. Bạn không bắt buộc phải tạo thông báo trong ứng dụng vì khung in tự động tạo thông báo hệ thống cho lệnh in.