Android でシンプルな写真以外のコンテンツを印刷するには、印刷ドキュメントでテキストとグラフィックを作成する必要があります。Android フレームワークでは、HTML を使用してドキュメントを作成し、最小限のコードでそれを印刷できます。
Android 4.4(API レベル 19)では WebView
クラスが更新され、HTML コンテンツを印刷できるようになりました。このクラスを使用すると、ローカルの HTML リソースを読み込むか、ウェブからページをダウンロードして印刷ジョブを作成し、Android の印刷サービスに渡すことができます。
このレッスンでは、テキストとグラフィックを含む HTML ドキュメントをすばやく作成し、WebView
を使用して出力する方法を示します。
HTML ドキュメントを読み込む
WebView
を使用して HTML ドキュメントを印刷するには、HTML リソースを読み込むか、HTML ドキュメントを文字列として作成する必要があります。このセクションでは、HTML 文字列を作成し、印刷のために WebView
に読み込む方法について説明します。
このビュー オブジェクトは、通常、アクティビティ レイアウトの一部として使用されます。ただし、アプリで WebView
を使用していない場合は、印刷専用にクラスのインスタンスを作成できます。このカスタム印刷ビューの主な作成手順は次のとおりです。
- HTML リソースの読み込み後に印刷ジョブを開始する
WebViewClient
を作成します。 - HTML リソースを
WebView
オブジェクトに読み込みます。
次のコード例は、シンプルな WebViewClient
を作成して、作成された HTML ドキュメントをその場で読み込む方法を示しています。
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; }
注: 印刷ジョブを生成するための呼び出しが、前のセクションで作成した WebViewClient
の onPageFinished()
メソッドで発生していることを確認してください。ページの読み込みが終わるまで待つと、印刷出力が不完全または空白になったり、完全に失敗したりすることがあります。
注: 上記のサンプルコードでは、WebView
オブジェクトのインスタンスを保持しているため、印刷ジョブの作成前にガベージ コレクションは行われません。ご自分の実装でも同様のようにしてください。そうしないと、印刷プロセスが失敗する可能性があります。
ページにグラフィックを含める場合は、以下のコードサンプルに示すように、プロジェクトの assets/
ディレクトリにグラフィック ファイルを配置し、loadDataWithBaseURL()
メソッドの最初のパラメータでベース URL を指定します。
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);
以下に示すように、loadDataWithBaseURL()
メソッドを loadUrl()
に置き換えて、印刷するウェブページを読み込むこともできます。
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");
印刷ドキュメントの作成に WebView
を使用する場合は、次の制限事項に注意してください。
- ページ番号などのヘッダーまたはフッターをドキュメントに追加することはできません。
- HTML ドキュメントの印刷オプションにページ範囲を印刷する機能はありません。たとえば、10 ページの HTML ドキュメントの 2 ~ 4 ページを印刷することはできません。
WebView
のインスタンスが処理できるのは、一度に 1 つの印刷ジョブだけです。- 横長プロパティなどの CSS 印刷属性を含む HTML ドキュメントはサポートされていません。
- HTML ドキュメントで JavaScript を使用して印刷をトリガーすることはできません。
注: レイアウトに含まれる WebView
オブジェクトのコンテンツは、ドキュメントが読み込まれた後も印刷できます。
よりカスタマイズされた印刷出力を作成し、印刷されるページのコンテンツ描画を完全に制御する場合は、次のレッスンのカスタム ドキュメントの印刷に進んでください。
印刷ジョブを作成する
WebView
を作成して HTML コンテンツを読み込んだら、アプリケーションの印刷プロセスのその部分はほぼ完了です。次の手順では、PrintManager
にアクセスして印刷アダプターを作成し、最後に印刷ジョブを作成します。次の例は、この手順を実行する方法を示しています。
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); }
この例では、アプリで使用する PrintJob
オブジェクトのインスタンスを保存しますが、これは必須ではありません。アプリケーションは、このオブジェクトを使用して、処理中の印刷ジョブの進行状況を追跡できます。この方法は、アプリケーションの印刷ジョブのステータス(完了、失敗、ユーザーによるキャンセル)をモニタリングする場合に便利です。印刷フレームワークによって印刷ジョブのシステム通知が自動的に作成されるため、アプリ内通知を作成する必要はありません。