Android でシンプルな写真以外のコンテンツを印刷するには、印刷ドキュメントでテキストとグラフィックを作成する必要があります。Android フレームワークには、最小限のコードで HTML を使ってドキュメントを作成し、印刷する機能が用意されています。
Android 4.4(API レベル 19)では、HTML コンテンツを印刷できるように WebView
クラスが更新されました。このクラスを使用すると、ローカル 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
オブジェクトのインスタンスが保存されますが、これは必須ではありません。アプリでは、このオブジェクトを使用して、処理中の印刷ジョブの進行状況を確認できます。このアプローチは、印刷ジョブの完了、失敗、ユーザーによるキャンセルなどのステータスをアプリで監視するときに役立ちます。印刷ジョブのシステム通知が印刷フレームワークによって自動的に作成されるため、アプリ内通知を作成する必要はありません。