WebView 内の HTML コンテンツの印刷

ここでは WebView 内に表示されている内容を印刷する方法を紹介します。

普通のアプリケーションでは、画面を印刷したいという要望はあまりないのですが、WebView のようなブラウザの機能では、 表示内容によっては印刷したい場合もありますよね。

例えばメールクライアントで、リスト表示になっているメールの一覧を印刷したい場合はあまりありませんが、それぞれのメールの内容自体は印刷したい場合もあるかもしれません。

画像は画像ファイルという単位で情報がまとまっているので、ファイル単位で情報を他のアプリケーション(特に印刷の場合は Cloud Print 等) に送信できるのはわかりやすいですが、WebView などは HTML とそこにロードされている画像などでひとつのビューが構成されているために、何をプリンターに送ればよいか自明ではありません。

先に答えを言うと、実は WebView には現在の表示内容を Picture オブジェクトとして取り出すメソッドがあり、それでスクリーンショットを取得できます。

ここではその実装方法をみてみましょう。

WebView 内のコンテンツを印刷する方法

ここで作るプログラムは次の通りです。

画面の上側大半が WebView です。最下部に "Send" ボタンを配置してあります。

WebView 内のコンテンツの印刷

この Send ボタンを押すと、現在 WebView に表示されている内容を印刷することができます。

WebView 内のコンテンツの印刷

さっそく実装を見てみましょう。レイアウトは次の通り。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical" >
  <WebView 
    android:id="@+id/webView1"
    android:layout_width="match_parent"
    android:layout_weight="1"
    android:layout_height="0dp"
    />
  <Button
    android:id="@+id/button1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Send"/>
</LinearLayout>

コードは次の通り。WebView を利用した HTML コンテンツの表示については、WebView のページ を確認してください。

package com.example.printtest2;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Calendar;

import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Picture;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.drawable.PictureDrawable;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;

public class MainActivity extends Activity
  implements OnClickListener {

  static final int REQUEST_CAPTURE_IMAGE = 100;
  WebView webView;
  Button button1;
  File webFile;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    webView = (WebView)findViewById(R.id.webView1);
    webView.setWebViewClient(new WebViewClient(){
      @Override
      public boolean shouldOverrideUrlLoading(
        WebView view, String url) {
        return false;
      }
    });
    button1 = (Button)findViewById(R.id.button1);
    webView.loadUrl("http://www.google.com/");
    button1.setOnClickListener(this);
  }

  @Override
  public void onClick(View v) {
    if(v.getId() == R.id.button1){
      sendContent();
    }
  }

  protected String getPicFileName(){
    Calendar c = Calendar.getInstance();
    String s = c.get(Calendar.YEAR)
      + "_" + (c.get(Calendar.MONTH)+1)
      + "_" + c.get(Calendar.DAY_OF_MONTH)
      + "_" + c.get(Calendar.HOUR_OF_DAY)
      + "_" + c.get(Calendar.MINUTE)
      + "_" + c.get(Calendar.SECOND)
      + ".jpg";
    return s;
  }

  private static Bitmap pictureDrawable2Bitmap(Picture picture) {
    PictureDrawable drawable = new PictureDrawable(picture);
    Bitmap bitmap = Bitmap.createBitmap(
      drawable.getIntrinsicWidth(),
      drawable.getIntrinsicHeight(),
      Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    canvas.drawPicture(drawable.getPicture());
    return bitmap;
  }

  protected void sendContent(){
    try {
      // WebView の表示内容を画像 (Picture オブジェクト) として取得
      Picture picture = webView.capturePicture();
      Bitmap  bitmap = pictureDrawable2Bitmap(picture);

      ByteArrayOutputStream outStream = new ByteArrayOutputStream();
      bitmap.compress(CompressFormat.JPEG, 80, outStream);
      byte[] imageInByte = outStream.toByteArray();

      // 画像ファイルとして保存
      File path = Environment.getExternalStoragePublicDirectory(
      Environment.DIRECTORY_PICTURES);
      path.mkdirs();
      File picFile = new File(path, getPicFileName());

      FileOutputStream fileOutStream = new FileOutputStream(picFile);
      fileOutStream.write(imageInByte);
      fileOutStream.close();

      // Send アクション
      Intent shareIntent = new Intent(Intent.ACTION_SEND);
      shareIntent.setType("image/jpeg");
      shareIntent.putExtra(
        Intent.EXTRA_STREAM, Uri.fromFile(picFile));
      startActivity(shareIntent);

    } catch (Exception e) {
      e.printStackTrace();
      return;
    }
  }
}

このコードのキモは最後の sendContent メソッドの部分です。WebView の内容をファイルに一旦保存して、それを他のアプリに送っています。 ファイルに書き出すために android.permission.WRITE_EXTERNAL_STORAGE パーミッションをアンドロイドマニフェストに追加する必要があります。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Android 開発入門