Edited at

AndroidのPrintManagerを使って画面を印刷する方法

More than 1 year has passed since last update.

mixiグループ Advent Calendar 2017 14日目の記事です。

株式会社ミクシィで新規事業の業務向けアプリを書いているakkumaです。

今回はAndroidで印刷をする方法を書きます。


プリントサービスプラグイン

まずAndroidの印刷API経由で好きな内容を印刷するには、Google play上で提供されているプリンターに対応したプリントサービスプラグインをインストールしてある必要があります。メーカーがプラグインを提供していれば、そのメーカーが出している最近のほとんどの機種で利用できる印象です。

キヤノンの例

http://cweb.canon.jp/apps/plug-in/printservice.html

エプソンの例

http://www.epson.jp/spmd/service_plugin/faq.htm#anchor12

またもちろんですが、プリンターにネットワーク経由でアクセスできる環境にいる必要があります。

メーカーのプリントサービスプラグインの実装によってはプリンターのIPアドレスを直接指定することができず、同一サブネット上からプリンターを検出するのみのタイプがあります。

そこは各社の実装に依存するので、プリンターを購入する前にプリントサービスプラグインの実装を確認することをおすすめします。


PrintManagerとPrintDocumentAdapter

Androidでの印刷機能へのアクセスはPrintManagerが担っています。Context#getSystemService()で取得することができます。

印刷したい内容をPDFで書き出すことで、プリンターに印刷指示を出すことができます。

そこで、指定の用紙条件で作成されたPDFをPrintManagerに渡すためにPrintDocumentAdapterを実装する必要があります。

PrintDocumentAdapterを独自実装する場合は公式の解説をご覧ください。

後述のBitmapWebView(Html)であればPrintDocumentAdapterを自分で実装せず簡単に印刷する事ができるため省略します。

PrintDocumentAdapterを利用した印刷の場合はPrintManager#print()を呼ぶことで印刷することができます。

PrintManager printManager = (PrintManager) context.getSystemService(Context.PRINT_SERVICE);

PrintDocumentAdapter adapter = new TestPrintDocumentAdapter(this);
printManager.print("job_name", adapter, null);


WebViewの印刷

WebViewでは、createPrintDocumentAdapter()に呼ぶことで表示内容を印刷するためのPrintAdapterが提供されています。

HTMLを生成すれば良いので、複雑なドキュメントの印刷を要求された場合の妥協点かと思います。

private void printWebView(WebView webView) {

PrintDocumentAdapter adapter = webView.createPrintDocumentAdapter();
PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
printManager.print("job_name", adapter, null);
}


Bitmapの印刷

サポートライブラリsupport-v4のPrintHelperがBitmapを印刷するためのヘルパーを提供していて、簡単に実装することができます。

private void printBitmap(Bitmap bitmap) {

PrintHelper printHelper = new PrintHelper(context);
printHelper.setColorMode(PrintHelper.COLOR_MODE_COLOR);
printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT);
printHelper.printBitmap("job_name", bitmap);
}

PrintAdapterの構造を意識しなくても印刷できます。


Viewの内容を印刷してみる

Bitmapさえ取得できれば簡単に印刷することができるので、ViewをBitmapに変換してからPrintHelperを使って印刷してみます。

せっかくなのでAndroidアプリを印刷したことを強調するためにgetWindow().getDecorView()を印刷してみます。

private void printWindow() {

View view = getWindow().getDecorView();
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);

PrintHelper printHelper = new PrintHelper(this);
printHelper.setColorMode(PrintHelper.COLOR_MODE_COLOR);
printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT);
printHelper.printBitmap("view", bitmap);
}

Activityが表示された状態でprintWindow()を実行すると

Activityの内容がそのまま印刷内容になった印刷設定が出ます。

あとは印刷するだけ