Tips

AndroidでPDFViewerを作成する 第1回

AndroidでPDFViewer

Androidでちょっとしたアプリケーションを作成してみようということで今回から何回かにわたってPDFViewerを作成する過程を紹介していきたいと思います。

この企画はObjective-C(Swift?)で同じアプリケーションを作成する企画(Objective-CでPDFViewerを作成する)と連動しています。AndroidとiPhoneでどのように違うのかというところも比較してみてもらえると、面白いかもしれません。

今回は、Eclipse(ADT-Bundle)を使用します。

AndroidでPDFViewerを作るためには

Objective-Cには、PDFを読み込むためのライブラリが含まれているようですが、あいにくとAndroidにはそのようなライブラリは組み込まれていません。Androidではインテントという仕組みがあり、PDFを見たいときには「他のViewerアプリに任せる」ことができるためかもしれません。

この連載では、アプリ内でPDFを表示させることを目指していますので、何らかのサードパーティ製ライブラリを使うことにします。
様々な方法があるようですが、今回はMuPDFを使用します。速度面、品質面、日本語対応など問題ないのですが、ライセンスが「ADPL」ですので使用する際はご注意ください。

Android NDK環境を構築する

Android SDKはインストールしてあるものとします。
まだの方は本ブログでもインストール方法を紹介していますので、そちらを参照ください。

では、Android NDKをインストールします。
公式ページからダウンロードします。お使いの環境に合わせて32bitもしくは64bit版をダウンロードしましょう。
一番左列のPlatformはAndroidのことだと思いますので、私はAndroidとWindowsがともに32bitのものをダウンロードしました。
WS000000

ダウンロードしたzipファイルを適当な場所へ解凍します。
私は、ADT-Bundleを解凍した「adt-bundle-windows-x86-xxxxxxxx」フォルダ直下へ「ndk」という名前で配置しました。
WS000002

次に、NDKをインストールしたフォルダを環境変数PATHへ設定します。「ndk」フォルダまでのパスでOKです。
WS000003

NDKの中にはサンプルアプリが同梱されているため、まずはそれを動かしてみます。
サンプルアプリは、ndk¥samplesフォルダにあるので、Eclipseでインポートを行います。
WS000007

インポートするときは、「Copy projects into workspace」にチェックを入れておくことをオススメします。
このチェックがないと、サンプルプログラムを修正したときに大本のファイルまで修正されてしまい、万が一壊してしまったときに元に戻せなくなるためです。

ここでは、「hello-jni」というプロジェクトをインポートしてみました。

次に、NDKを使ってコンパイルを行います。
コマンドプロンプトを立ち上げ、「HelloJni」フォルダまで移動したあとに、「ndk-build」コマンドを実行します。

>cd 「workspaceのパス」¥HelloJni

>ndk-build
Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minSdkVersion 3 in ./AndroidManifest.xml
[armeabi-v7a] Gdbserver      : [arm-linux-androideabi-4.6] libs/armeabi-v7a/gdbserver
[armeabi-v7a] Gdbsetup       : libs/armeabi-v7a/gdb.setup
[armeabi] Gdbserver      : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
[armeabi] Gdbsetup       : libs/armeabi/gdb.setup
[x86] Gdbserver      : [x86-4.6] libs/x86/gdbserver
[x86] Gdbsetup       : libs/x86/gdb.setup
[mips] Gdbserver      : [mipsel-linux-android-4.6] libs/mips/gdbserver
[mips] Gdbsetup       : libs/mips/gdb.setup
[armeabi-v7a] Compile thumb  : hello-jni <= hello-jni.c
[armeabi-v7a] SharedLibrary  : libhello-jni.so
[armeabi-v7a] Install        : libhello-jni.so => libs/armeabi-v7a/libhello-jni.so
[armeabi] Compile thumb  : hello-jni <= hello-jni.c
[armeabi] SharedLibrary  : libhello-jni.so
[armeabi] Install        : libhello-jni.so => libs/armeabi/libhello-jni.so
[x86] Compile        : hello-jni <= hello-jni.c
[x86] SharedLibrary  : libhello-jni.so
[x86] Install        : libhello-jni.so => libs/x86/libhello-jni.so
[mips] Compile        : hello-jni <= hello-jni.c
[mips] SharedLibrary  : libhello-jni.so
[mips] Install        : libhello-jni.so => libs/mips/libhello-jni.so

正常にコンパイルが行われれば、「libs」フォルダが新しく作成され、その中にコンパイルしてできたファイルが格納されているはずです。

実行すると以下のような画面が表示されるはずです。
device-2014-07-29-132059

Cygwin環境を構築する

MuPDFをAndroidで使えるようにするには、公式サイトからソースコードをダウンロードし、makeしなくてはなりません。
LinuxやMacを使えば簡単にできるのでしょうが、ここではWindowsのCygwin環境でコンパイルしてみたいと思います。

公式サイトからインストーラーをダウンロードします。
こちらも32bit版と64bit版がありますので、お使いの環境に合わせてダウンロードしてください。
公式サイト:https://www.cygwin.com/

WS000008

基本的には「次へ」で進んでいきます。
「Download site」を選ぶ画面では、日本のサイト(ここでは「ftp://ftp.jaist.ac.jp」)を選びましょう。
WS000014

次にインストールするパッケージを選択します。
必要なものは「make」と「gcc」です。それぞれ、検索ウィンドウで検索し「Devel」の中にあるものを選択します。「skip」と書かれているところをクリックすると、チェックが入り、インストールされるバージョンが表示されます。
WS000015

「gcc-core」「gcc-g++」を選択します。
WS000016

インストールが開始されますが、かなり時間がかかります。ゆっくり待ちましょう。

インストールが完了したら、デスクトップにあるアイコンでCygwinターミナルを起動します。
WS000020

MuPDFをmakeする

MuPDFのソースコードを公式サイトからダウンロードします。
公式サイト:http://www.mupdf.com/
WS000019

圧縮形式が「tar.gz」となっているため、Cygwinで解凍しましょう。
Cygwinでは、Cドライブにアクセスするときには「/cygdrive/c」ディレクトリを使います。

$ cd /cygdrive/c/Users/「ユーザー名」/Downloads/
$ tar xzvf mupdf-1.5-source.tar.gz

makeコマンドを実行します。

$ cd mupdf-1.5-source
$ make generate
    MKDIR build/debug
    CC build/debug/cmapdump.o
    LINK build/debug/cmapdump
    GEN generated/gen_cmap_cns.h
    GEN generated/gen_cmap_gb.h
    GEN generated/gen_cmap_japan.h
    GEN generated/gen_cmap_korea.h
    CC build/debug/fontdump.o
    LINK build/debug/fontdump
    GEN generated/gen_font_base14.h
    GEN generated/gen_font_droid.h
    GEN generated/gen_font_cjk.h
    GEN generated/gen_font_cjk_full.h
    CC build/debug/cquote.o
    LINK build/debug/cquote
    GEN generated/gen_js_util.h
    CC build/debug/bin2hex.o
    LINK build/debug/bin2hex
    GEN generated/gen_adobe_ca.h

MuPDFをNDKでコンパイルする

Android SDKのパスを設定します。
MuPDFを解凍してできたフォルダ内の「platform¥android」フォルダに「local.properties.sample」があります。
これをコピーして「local.properties」を作成します。
変更するのは9行目のみです。お使いの環境に合わせてパスを設定してください。

# Uncomment and edit the appropriate line below.
# Resave this file as local.properties.

# For MacOS/Linux you want a line such as:
#sdk.dir=/Library/android-sdk-mac_x86

# For Windows/Cygwin you want something like the following:
#sdk.dir=C:¥¥Program Files (x86)¥¥Android¥¥android-sdk
sdk.dir=「adt-bundleへのパス」¥¥sdk

コンパイル時に発生するエラー対策のため、「Application.mk」ファイルに以下の1文を追加します。

APP_CFLAGS += -Wno-error=format-security

それでは、NDKでコンパイルしましょう。
今度はコマンドプロンプトから操作します。

>cd 「MuPDFのソースフォルダ」¥platform¥android
>ndk-build
...中略...
[armeabi-v7a] Compile thumb  : mupdfthirdparty <= psaux.c
[armeabi-v7a] Compile thumb  : mupdfthirdparty <= pshinter.c
[armeabi-v7a] Compile thumb  : mupdfthirdparty <= psnames.c
[armeabi-v7a] Compile thumb  : mupdfthirdparty <= raster.c
[armeabi-v7a] Compile thumb  : mupdfthirdparty <= smooth.c
[armeabi-v7a] Compile thumb  : mupdfthirdparty <= sfnt.c
[armeabi-v7a] Compile thumb  : mupdfthirdparty <= truetype.c
[armeabi-v7a] Compile thumb  : mupdfthirdparty <= type1.c
[armeabi-v7a] StaticLibrary  : libmupdfthirdparty.a
[armeabi-v7a] SharedLibrary  : libmupdf.so
[armeabi-v7a] Install        : libmupdf.so => libs/armeabi-v7a/libmupdf.so

MuPDFサンプルアプリケーションを実行する

全ての準備が完了しました。
Eclipseでプロジェクトをインポートし、実行してみてください。
インポート時に指定するフォルダは「platform¥android」で、「Copy projects into workspace」にチェックを入れるのを忘れずに行いましょう。

また、エミュレータを使うときには、CPUを「armeabi-v7a」にしないとエラーとなりますので、ご注意を!

起動するとAndroidのダウンロードフォルダが表示されます。簡単なエクスプローラーが実装されているようです。
device-2014-07-29-154915

PDFを選択するとビューアーが起動します。拡大や縮小、ページ遷移なども問題なく動作しました。
また、表示速度に関しても問題ないように感じます。
device-2014-07-29-154937

手書きメモやハイライト表示も行えるようです。
device-2014-07-29-155027

第1回としてはかなりボリュームが大きくなってしまいました。
次回はMuPDFアプリケーションの中身を確認し、必要な機能のみを抜き出してくる作業を行いたいと思います。

次回MuPDFライブラリを覗いてみる

Androidアプリ開発の必須知識!JAVAプログラミングを学べる連載リンク

はじめてのJAVA 連載

Recent News

Recent Tips

Tag Search