Intelligent Technology's Technical Blog

株式会社インテリジェントテクノロジーの技術情報ブログです。

Androidアプリ内でPDFを表示する - MuPDFの場合(その2) -

こんにちは、中山です。

前回の記事「Androidアプリ内でPDFを表示する - MuPDFの場合(その1) -」では、「MuPDF」ライブラリをビルドして、そのAndroid用サンプルアプリを実行するところまでをご紹介いたしました。

今回はさらに、この「MuPDF」ライブラリを、自作のAndroidアプリに組み込んでみようと思います。
必要な手順は、これから紹介する5つのステップだけです。

0.(準備)

前回の記事を参考に、「MuPDF」ライブラリをビルドして、そのAndroid用サンプルアプリを実行できる状態にしておきます。(詳細は割愛いたします。)
 

1.自作アプリの用意

Eclipseから、Androidアプリのプロジェクトを新規作成します。
もしくは、既存のプロジェクトを利用してもよいでしょう。
今回は、「MyMuPdfSample」という名前のアプリのプロジェクトを新規作成しました。(パッケージ名は「jp.co.iti.mymupdfsample」です。)
f:id:IntelligentTechnology:20131113105136p:plain

以降、この「MyMuPdfSample」アプリのプロジェクトを例に、説明していきます。
 

2.「MuPDF」ネイティブライブラリファイルの貼り付け

「MuPDF」サンプルアプリのプロジェクトから、「libs」フォルダとその中のファイルをコピーして、「MyMuPdfSample」アプリのプロジェクト内に貼り付けます。
f:id:IntelligentTechnology:20131113171143p:plain

3.リソースファイルの貼り付け

「MuPDF」サンプルアプリのプロジェクトから、必要なリソースファイル(=「res」フォルダ内のファイル)をコピーして、「MyMuPdfSample」アプリのプロジェクト内に貼り付けます。

3-1.「values」フォルダ

まずは「values」フォルダのファイルから。
f:id:IntelligentTechnology:20131113110107p:plain

colors.xml」「strings.xml」「styles.xml」を貼り付けます。もともと「MyMuPdfSample」プロジェクトに存在する「strings.xml」や「styles.xml」と区別するために、今回はそれぞれ「mupdf_colors.xml」「mupdf_strings.xml」「mupdf_styles.xml」に名称変更しました。

また、日本語環境用の「strings.xml」も、同様に「mupdf_strings.xml」に改名して貼り付けました。

・・・しかし上記を見ていただくとわかるとおり、エラーが出てしまっています。これは、「app_name」定義が、もともとの「strings.xml」と「mupdf_strings.xml」とで重複しているためです。
f:id:IntelligentTechnology:20131113110633p:plain

「mupdf_strings.xml」のほうの「app_name」定義を削除することで、このエラーは出なくなりました。
(実際には「mupdf_style.xml」でもエラーが出るのですが、これは次の「3-2」の手順によって解消できるため、ここではそのままとします。)

3-2.「animator」「drawable」フォルダ

次は「animator」「drawable」フォルダのファイルです。
これらはそのまま、「MuPDF」サンプルアプリのプロジェクトから、「MyMuPdfSample」プロジェクトに貼り付けてよいでしょう。
f:id:IntelligentTechnology:20131113110908p:plain

3-3.「drawable-mdpi」フォルダ

同様に「drawable-mdpi」フォルダのファイルを貼り付けます。
「MuPDF」サンプルアプリのプロジェクトから、「icon.png」以外のファイルを選択し、「MyMuPdfSample」プロジェクトに貼り付けました。
f:id:IntelligentTechnology:20131113111248p:plain

3-4.「layout」フォルダ

最後に「layout」フォルダのファイルを貼り付けます。
「MuPDF」サンプルアプリのプロジェクトから、「buttons.xml」「outline_entry.xml」「picker_entry.xml」「print_dialog.xml」「textentry.xml」をコピーして、「MyMuPdfSample」プロジェクトに貼り付けます。
f:id:IntelligentTechnology:20131113111450p:plain

4.ソースファイルの貼り付け

4-1.Javaソースファイルの貼り付け

「MuPDF」サンプルアプリのプロジェクトから、Javaソースファイルをすべて(「Annotation.java」から「WidgetType.java」まで、全部で36ファイル)、そのまま「MyMuPdfSample」プロジェクトに貼り付けます。
(実際には利用しないクラスのソースファイルもありますが、今回は便宜上、すべてのファイルを貼り付けの対象とします。)
f:id:IntelligentTechnology:20131113111936p:plain

このとき注意しないといけないのは、「MuPDF」サンプルアプリから、パッケージ構成もそのままでJavaソースファイルを「MyMuPdfSample」プロジェクトのほうに持ってくる、という点です。

今回の「MyMuPdfSample」プロジェクトのパッケージ名は「jp.co.iti.mymupdfsample」です。この中に、例えば「mupdf」フォルダを用意して、そこに上記のJavaソースファイルを配置する、という方法も可能です。
しかしこの場合、「MuPDF」のネイティブライブラリを呼び出すための設定を調整したり、あるいはライブラリをビルドし直したり、という操作が必要になってきます。

今回は、「MuPDF」サンプルアプリのプロジェクトから、パッケージ名そのままでJavaソースファイルを持ってくる、という方法をとることで、この手間を避けるようにしました。

4-2.ビルドエラーの解消

Javaソースファイルを「MyMuPdfSample」プロジェクトに持ってくると、上記のスクリーンショットのとおり、いくつかビルドエラーが出ます。
ソースファイルを見ると、「jp.co.iti.mymupdfsample.R」クラスが見つからない、というエラーのようです。
f:id:IntelligentTechnology:20131113113411p:plain

エラーが出ているソースファイルの先頭に、以下のように「import」文を追加することで、ビルドエラーを解消することができます。
f:id:IntelligentTechnology:20131113113505p:plain

4-3.AndroidManifest.xmlへの、Activity定義の登録

AndroidManifest.xmlに、以下の通りActivity定義を追加します。

<activity
  android:name="com.artifex.mupdfdemo.MuPDFActivity"
  android:theme="@style/AppBaseTheme"
  android:label="@string/app_name">
  <intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:mimeType="application/vnd.ms-xpsdocument"/>
  </intent-filter>
  ・・・
</activity>
<activity
  android:name="com.artifex.mupdfdemo.OutlineActivity"
  android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"
  android:label="@string/outline_title">
</activity>
<activity
  android:name="com.artifex.mupdfdemo.PrintDialogActivity"
  android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"
  android:label="@string/print">
</activity>

ファイルの全体は、こちらをご覧ください。
 

5.PDF表示機能の追加とアプリの実行

今回作成している「MyMuPdfSample」プロジェクトのメインのActivityである、「MainActivity」クラスに、以下のようなPDF表示のためのメソッドを追加します。

private void showPdf() {
  String filePath = Environment.getExternalStorageDirectory()
                    + "/mysample.pdf";

  Uri uri = Uri.parse(filePath);

  Intent intent = new Intent(this, MuPDFActivity.class);
  intent.setAction(Intent.ACTION_VIEW);
  intent.setData(uri);

  try {
    startActivity(intent);
  } catch (ActivityNotFoundException e) {
    e.printStackTrace();
  }
}

また、「MainActivity」の画面上のボタンをタップしたときに、このメソッドが呼ばれるようにします。

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

  Button buttonShowPdf = (Button)findViewById(R.id.button_show_pdf);
  buttonShowPdf.setOnClickListener(new View.OnClickListener() {			
    @Override
    public void onClick(View view) {
      MainActivity.this.showPdf();
    }
  });
}

ファイルの全体は、こちらをご覧ください。

ここまでできましたら、あとは実行するだけです。アプリを起動して、
f:id:IntelligentTechnology:20131113114651p:plain:w320

「Show PDF」ボタンをタップすると、指定されたパスのPDFが表示されます。
(あらかじめ、Android端末またはエミュレータの外部ストレージフォルダ(「/mnt/sdcard」など)に「mysample.pdf」という名前のPDFファイルを配置しておく必要があります。)
f:id:IntelligentTechnology:20131113114938p:plain:w320

今回作成した「MyMuPdfSample」アプリのソースは、こちらからご利用ください。
(ライセンスが「AGPL」となっていますので、ご注意ください。)
 

さらなる改良

ここまでの手順で、自作のAndroidアプリに「MuPDF」ライブラリを組み込む方法がわかりました。

後はこれにどんどん改良を加えていけば、きっと、より使いやすいPDFビューアになっていくことでしょう。
また、不要な機能をそぎ落として、よりシンプルなビューアを目指してもよいかもしれません。(実際、今回のアプリでも、「com.artifex.mupdfdemo」パッケージの「ChoosePDFActivity」クラスと、その関連クラスの機能は利用していません。)

「com.artifex.mupdfdemo」パッケージの「MuPDFActivity」クラスが、PDFビューアのメインとなるクラスです。このクラスの実装内容を参考にしたりしながら、独自のアイデアのヒントが見つかっていくかもしれませんね。