在应用程序中集成MuPDF Reader

46

我正在开发一个能够在我的应用程序中读取PDF的功能,并且希望将PDF视图放置在我的自定义布局中。我本来想使用Android PDF Viewer,但是当我执行缩放时,它需要太长时间了。

因此,我现在打算使用MuPDF开源项目来集成到我的项目中,它基于JNI,而我不熟悉JNI。

我正在使用Cygwin构建本地代码库。 因此,我不清楚以下几个问题:

  1. 如何将MuPDF集成到我的项目中(根据我的问题标题)?

  2. 一旦成功集成,我该如何将PDF阅读器放入我的自定义视图中(在XML或编程方式中)?


9
相信我,兄弟,如果你打算集成它,那么请准备至少一个繁忙的星期。 - ingsaurabh
1
是的,不仅仅是我所使用过的每个PDF库都是如此,而且你无法达到你想要的效果,它们都很慢且没有文档。 - ingsaurabh
1
@rasen58 不,它并不完全允许您将其用于商业目的,您需要通过发送详细信息到sales@artifex.com来说服他们。 - dharmendra
1
@Mr.Hyde 已经接受的答案对我已经起作用了。 - dharmendra
@dhams 但我想要一个卷曲/翻转的效果!你有什么想法或示例代码吗?! - Dr.jacky
显示剩余8条评论
6个回答

49

我不知道如何在Windows上使用cygwin做到这一点,因为我正在使用Ubuntu进行开发。但我认为流程应该是相同的。

  1. 从此处下载文件mupdf-0.9-source.tar.gz:http://code.google.com/p/mupdf/downloads/list?q=source
  2. 下载文件mupdf-thirdparty.zip
  3. 解压源代码,默认情况下它们将被解压缩到文件夹mupdf-0.9/中
  4. 将文件mupdf-thirdparty.zip解压到文件夹mupdf-0.9/中
  5. 构建项目mupdf-0.9(对于Windows,您应该使用VS,因为在自述文件中声明了这一点)
  6. 然后进入文件夹mupdf-0.9/android/
  7. 运行ndk-build
  8. 您可能会遇到以下错误:

Compile thumb : mupdfthirdparty <= jbig2.c In file included from /home/yury/programming/android/workspace/mupdf-0.9/android/jni/../../thirdparty/jbig2dec/os_types.h:53, from /home/yury/programming/android/workspace/mupdf-0.9/android/jni/../../thirdparty/jbig2dec/jbig2.c:22: /home/yury/software/android-ndk-r6b/platforms/android-8/arch-arm/usr/include/stdint.h:48: error: redefinition of typedef 'int8_t' /home/yury/programming/android/workspace/mupdf-0.9/android/jni/../../thirdparty/jbig2dec/os_types.h:47: note: previous declaration of 'int8_t' was here

解决方法在这里解释:mupdf for android: ndk-build problem (error: redefinition of typedef....) 但是,您可以简单地注释/thirdparty/jbig2dec/os_types.h文件中类型定义的行。

之后,您将获得两个库:一个静态库和一个共享库,可供您的Android应用程序使用。

StaticLibrary  : libmupdfthirdparty.a
SharedLibrary  : libmupdf.so

这是第一个问题的答案。在android/Readme.txt文件中还有一个很棒的步骤指南。

现在回答第二个问题。 在android应用程序中,您可以找到测试项目。其中包含3个文件:

  • MuPDFActivity.java
  • MuPDFCore.java
  • PixmapView.java

只需将最后两个文件复制到您的项目中。并参考MuPDFActivity.java中的示例,了解如何在您的活动中嵌入mupdf布局。在该文件中,它是这样完成的:

    PixmapView pixmapView;
//...   
layout = new RelativeLayout(this);
//...
    RelativeLayout.LayoutParams pixmapParams =
                      new RelativeLayout.LayoutParams(
                                RelativeLayout.LayoutParams.FILL_PARENT,
                                RelativeLayout.LayoutParams.FILL_PARENT);
    pixmapParams.addRule(RelativeLayout.ABOVE,100);
    layout.addView(pixmapView, pixmapParams);

    setContentView(layout);

是的,我想提到这一点,但这不是问题所在) - Yury
1
你能否提出一个单独的问题,并将所有错误堆栈放在那里吗? - Yury
2
较新版本的mupdf不再具备PixMapView类。 - harveyslash
我尝试了你的解决方案,但是出现了以下错误: java.lang.UnsatisfiedLinkError: No implementation found for long com.archaio.airs.MuPDFCore.openFile(java.lang.String) (tried Java_com_archaio_airs_MuPDFCore_openFile and Java_com_archaio_airs_MuPDFCore_openFile__Ljava_lang_String_2) - Jay Vyas
我的应用程序崩溃并出现以下错误: 01-01 17:25:50.357: E/AndroidRuntime(14330): java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.artifex.mupdfdemo-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libmupdf.so"我该如何解决这个问题? - patel135
显示剩余2条评论


7
这是我在我的Mac上(2012年,Intel i5)实现的方法:
第1步:获取mupdf-1.2-source.zip 第2步:获取android-ndk-mac-64 第3步:将它们都解压到一个名为Android-pdf的新文件夹中,并将解压缩文件夹重命名为mupdfandroid-ndk(您可以随意更改名称)
第4步:打开终端并使用命令:cd,直到您进入android-pdf文件夹
第5步:输入命令cd mupdf,然后输入命令make(大约需要40秒来运行所有脚本)
第6步:输入命令cd android(位于mupdf目录中)
步骤7:打开Finder并进入文件夹Android-pdf,然后将android-ndk中的文件ndk-build拖到终端命令行中并输入(基本上是添加一个路径到ndk-build以操作mupdf库)。几秒钟后,您应该在mupdf > android > libs > ...内部有一个新文件夹,将其用于您的Android项目。
如何将MuPDF与现有的Eclipse项目一起使用:
  1. 将/android文件夹中的'jni'文件夹复制到您现有的Eclipse项目中。
  2. 将/thirdparty文件夹复制到您项目中的'jni'文件夹中。
  3. 将/cbz文件夹复制到您项目中的'jni'文件夹中。
  4. 将/draw文件夹复制到您项目中的'jni'文件夹中。
  5. 将/fitz文件夹复制到您项目中的'jni'文件夹中。
  6. 将/generated文件夹复制到您项目中的'jni'文件夹中。
  7. 将/pdf文件夹复制到您项目中的'jni'文件夹中。
  8. 将/scripts文件夹复制到您项目中的'jni'文件夹中。
  9. 将/xps文件夹复制到您项目中的'jni'文件夹中。
  10. 打开'jni'文件夹内的'Android.mk'文件。
  11. 更改

    MUPDF_ROOT := ..

MUPDF_ROOT := $(TOP_LOCAL_PATH)
  1. 保存“Android.mk”文件。
  2. 打开“jni”文件夹中的“Core.mk”文件。
  3. 更改为

    MY_ROOT:= ../..

MY_ROOT := $(LOCAL_PATH)
  1. 将LOCAL_C_INCLUDES中的所有

    ..

更改为

$(LOCAL_PATH)
  1. 保存'Core.mk'文件。
  2. 打开'jni'文件夹内的'ThirdParty.mk'文件。
  3. MY_ROOT := ../..

修改为

MY_ROOT := $(LOCAL_PATH)

将LOCAL_C_INCLUDES中的所有内容更改为:
$(LOCAL_PATH)

  1. 保存 'ThirdParty.mk' 文件。
  2. 现在在你项目的 'jni' 目录下执行 'ndk-build' 命令。
  3. 将 /android/src 文件夹中的所有内容复制到你项目的 'src' 文件夹中。
  4. 将 /android/res/drawable 文件夹中的所有内容复制到你项目的 'res/drawable' 文件夹中。
  5. 将 /android/res/drawable-ldpi 文件夹中的所有内容复制到你项目的 'res/drawable-ldpi' 文件夹中。
  6. 将 /android/res/drawable-mdpi 文件夹中的所有内容复制到你项目的 'res/drawable-mdpi' 文件夹中。
  7. 将 /android/res/layout 文件夹中除了 main.xml 之外的所有内容(因为如果你正在将其复制到现有项目中,则应该已经有自己的 main.xml 或等效文件)复制到你项目的 'res/layout' 文件夹中。
  8. 将 /android/res/values 文件夹中的所有内容复制到你项目的 'res/values' 文件夹中。如果你的现有项目中已经有一个 'strings.xml' 文件,则将 /android/res/values/strings.xml 文件中 '' 标签之间的所有内容复制到你项目的 strings.xml 文件中(粘贴到 '' 标签之间)。类似地,如果你的现有项目中已经有一个 'colors.xml' 文件,则将 /android/res/values/colors.xml 文件中 '' 标签之间的所有内容复制到你项目的 colors.xml 文件中(粘贴到 '' 标签之间)。
  9. 打开项目中的 'AndroidManifest.xml' 文件。
  10. 在 '' 标签之间,将 /android 文件夹中的 AndroidManifest.xml 文件中的所有活动列表粘贴进去。 你应该从 mupdf 中的 AndroidManifest.xml 的工作副本中复制

  11. MuPDF 现在已经在你现有的 Eclipse 项目中。要使用它,请在你的应用程序中调用 com.artifex.mupdf.ChoosePDFActivity.class。这是 MuPDF 的主类。

  12. 要使用前缀文件打开 pdf:

    Uri uri = Uri.parse("pdf 文件路径");

    Intent intent = new Intent(context, MuPDFActivity.class);

    intent.setAction(Intent.ACTION_VIEW);

    intent.setData(uri);

    context.startActivity(intent);

希望这有所帮助 :)

步骤6:cd android(在mupdf目录中) -bash:cd:android:没有那个文件或目录 - itsazzad
2
@SazzadHossainKhan 现在是平台/安卓。 - akauppi

5
请查看这个项目:eBookDroid

EBookDroid is an open source (GPL'ed) document viewer for Android based on the VuDroid code base.

Supported the file in following formats:

PDF
DjVu
XPS (OpenXPS)
comics books (cbz,cbr)

如果存在路径问题,请在src文件夹中搜索该文件,或者只需下载apk并从中提取lib,就这么简单。 - ingsaurabh
你试过这个吗?它是最快的,但你必须提取PDF模块,这很繁琐。它是最好的选择,也是最快的。 - ingsaurabh
我尝试过这个,但在缩放PDF时出现问题,由于位图超出VM而强制关闭。 - Lalit Poptani
实际上这取决于PDF文件本身。如果它包含过多的高分辨率图像,那么我的项目将对此进行处理,因为它大多数情况下要渲染矢量文本和一些图像,所以可以很好地完成任务。另外,缩放功能存在一些错误,你需要修改Java代码来解决。 - ingsaurabh
自从2版本以后,EBookDroid成为了一个闭源应用程序。所有第三方GPL代码都被删除或移动到单独的程序中。 - itsazzad
显示剩余2条评论

0

star18bit 给出的答案基本上概括了一切,但即使按照那个方法,我仍然遇到了很多问题。

比如 make 命令对我不起作用,我不得不使用 Visual Studio 进行构建。所以我列出了所有的先决软件,例如 ANT。此外,我们需要将 sdk 文件夹中的 toolsplatform-tools 文件夹添加到 PATH 中。

此外,我还必须在 Core2.mk 文件中进行更改,同样的更改也要在 Core.mk 中进行。我无法在这里提供所有信息,因为它太多了,所以我推荐参考以下链接获取完整信息:

http://howtojava.net/tutorials/android/integrate-mupdf-with-android-in-windows-7


2
虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。 - Werner
我在答案中添加了更多信息,并给出了链接,因为我无法在此处写出所有步骤。而且礼貌的做法是请求别人修改他们的评论,而不是直接删除它。 - nullpointer
您试图回答一个三年前的问题,该问题已经有了多个(被赞同的)答案。此外,您似乎在为另一个答案添加信息。这可能更适合作为评论而不是完整的答案。这是我的意见...其他人可能有不同的看法,也没问题。 - Werner
虽然这个问题已经存在了三年,但是对于我来说它仍然是个问题,即使有很多赞同的答案也无法解决。而且这些答案都没有帮到我。这就是为什么我想要将我的解决方案单独添加为一个答案。 - nullpointer

0
我在我的应用程序中有一个视图翻页器。我需要在视图翻页器的每个片段中显示pdf文件。是否有办法从mupdf获取pdf视图?通常我们如下所示调用mupdf。
Uri uri = Uri.parse("path to pdf file");

Intent intent = new Intent(context, MuPDFActivity.class);

intent.setAction(Intent.ACTION_VIEW);

intent.setData(uri);

context.startActivity(intent);

所以如果我在我的应用程序中使用mupdf,我必须在每个片段中调用MuPDFActivity。我认为这不是正确的方式?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接