Android 4.4 でもPdfRendererを使えるようするライブラリを作りました

More than 1 year has passed since last update.

PdfRendererはSDKに追加されたPDFレンダリング用のクラスですが、Android 5.0(API Level 21)未満の端末では使えません。しかしPDFを表示するアプリケーションを作るにあたって4.4以下の端末のサポートを諦めるというのはあまりいい選択ではありません。

しかし、Androidで使える無料のオープンソースのPDFレンダリングエンジンというものは基本的にないといっていいです。あるとしてもとても高価な商用のライブラリ(しかもあまり信用出来ない)であったりとあまりいい感じではありません。

というわけで本題ですが、Android 4.4(API Level 19)でも使えるPdfRenderer互換のライブラリを作りました。

https://github.com/loilo-inc/loilo-pdf

Gradleなら以下のようにbuild.gradleに記入することで使えます。

repositories {
    maven {
        url 'http://oss.sonatype.org/content/repositories/snapshots'
    }
}

dependencies {
  compile 'tv.loilo.pdf:pdfcompat:0.2.1-SNAPSHOT'
}

使い方はこんな感じ。オリジナルのPdfRendererと完全に同じインターフェースになってます。ライセンスはオリジナルと同じApache 2.0です。

MainActivity.java
// pdf file
File file = new File("file.pdf");
try (ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,ParcelFileDescriptor.MODE_READ_ONLY);
     PdfRendererCompat renderer = new PdfRendererCompat(fd);
) {
    for (int i = 0; i < renderer.getPageCount(); i++) {
        try(PdfRendererCompat.Page page = renderer.openPage(i)){
             Bitmap out = Bitmap.createBitmap(page.getWidth(), page.getHeight(), Bitmap.Config.ARGB_8888);
             Matrix mat = new Matrix();
             mat.setScale(2,2);
             page.render(out, null, mat, PdfRendererCompat.Page.RENDER_MODE_FOR_DISPLAY);
        }
    }
}

仕組み

Android、というかGoogle ChromeはもともとFoxit SDKという商用のPDFレンダリングエンジンをライセンスして使用していたようなのですが、Android 5.0になるタイミングでpdfiumという名前でオープンソース化しました。ここらへんの事情はよくわかりません。

しかしOSSになったので一応pdfiumのソースはAOSPのリポジトリに存在しています。AndroidのPDF関連の処理はほぼ全てがJNIでネイティブのシェアードライブラリを呼んでいるだけなので、
Android5.0のリポジトリからpdfiumの部分とPdfRendererのJavaクラスをforkしてNDKでビルドすれば、シェアードライブラリとJNIクラスが作れるのでは?というところからスタートしました。

pdfiumのNDKビルドにとても苦労しましたが、なんとか4.4で動く.soをビルドすることができました。

4.4未満

ソースコードを見る限りではビルドできそうなのですがJNIの闇に飲まれてビルドできませんでした。ビルドできたという方はプルリクをいただければと思います。