Android内嵌MuPDF打开PDF文件

一、基本实现

       1,导入so库;

Android内嵌MuPDF打开PDF文件_第1张图片

        2,声明库文件中方法

public class MuPDFCore {
	/* load our native library */
	static {
		System.loadLibrary("mupdf");
	}

	/* Readable members */
	private int pageNum = -1;;
	private int numPages = -1;
	public float pageWidth;
	public float pageHeight;

	/* The native functions */
	private static native int openFile(String filename);

	private static native int countPagesInternal();

	private static native void gotoPageInternal(int localActionPageNum);

	private static native float getPageWidth();

	private static native float getPageHeight();

	public static native void drawPage(Bitmap bitmap, int pageW, int pageH,
			int patchX, int patchY, int patchW, int patchH);

	public static native RectF[] searchPage(String text);

	public static native int getPageLink(int page, float x, float y);

	public static native boolean hasOutlineInternal();

	public static native boolean needsPasswordInternal();

	public static native boolean authenticatePasswordInternal(String password);

	public static native void destroying();

	public MuPDFCore(String filename) throws Exception {
		if (openFile(filename) <= 0) {
			throw new Exception("Failed to open " + filename);
		}
	}

	public int countPages() {
		if (numPages < 0)
			numPages = countPagesSynchronized();
		return numPages;
	}

	private synchronized int countPagesSynchronized() {
		return countPagesInternal();
	}

	/* Shim function */
	public void gotoPage(int page) {
		if (page > numPages - 1)
			page = numPages - 1;
		else if (page < 0)
			page = 0;
		if (this.pageNum == page)
			return;
		gotoPageInternal(page);
		this.pageNum = page;
		this.pageWidth = getPageWidth();
		this.pageHeight = getPageHeight();
	}

	public synchronized PointF getPageSize(int page) {
		gotoPage(page);
		return new PointF(pageWidth, pageHeight);
	}

	public synchronized void onDestroy() {
		destroying();
	}

	public synchronized void drawPage(int page, Bitmap bitmap, int pageW,int pageH, int patchX, int patchY, int patchW, int patchH) {
		gotoPage(page);
		drawPage(bitmap, pageW, pageH, patchX, patchY, patchW, patchH);
	}

	public synchronized int hitLinkPage(int page, float x, float y) {
		return getPageLink(page, x, y);
	}

	public synchronized RectF[] searchPage(int page, String text) {
		gotoPage(page);
		return searchPage(text);
	}

	public synchronized boolean hasOutline() {
		return hasOutlineInternal();
	}

	public synchronized boolean needsPassword() {
		return needsPasswordInternal();
	}

	public synchronized boolean authenticatePassword(String password) {
		return authenticatePasswordInternal(password);
	}
}

           
    3,使用 
  

public class MuPDFActivity extends BaseActivity {
	private MuPDFCore core;
	private String mFileName;
	private ListView mDocListView;
	private View mButtonsView;
	private boolean mButtonsVisible;
	private EditText mPasswordView;
	private TextView mFilenameView;
	private SeekBar mPageSlider;
	private TextView mPageNumberView;
	private ViewSwitcher mTopBarSwitcher;

	private ProgressBar loadingPB;

	private MyMuPDFPageAdapter pdfPageAdapter;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		if (core == null) {
			File sdcardDir = Environment.getExternalStorageDirectory();
			// 得到一个路径,内容是sdcard的文件夹路径和名字
			String path = sdcardDir.getPath() + "/MyMobileDownlod/test.pdf";

			int lastSlashPos = path.lastIndexOf('/');
			mFileName = new String(lastSlashPos == -1 ? path
					: path.substring(lastSlashPos + 1));
			System.out.println("Trying to open " + path);
			try {
				core = new MuPDFCore(path);
			} catch (Exception e) {
			}

			if (core != null && core.needsPassword()) {
				return;
			}
		}
		if (core == null) {
			AlertDialog alert = new AlertDialog.Builder(this).create();
			alert.setTitle(R.string.open_failed);
			alert.setButton(AlertDialog.BUTTON_POSITIVE, "Dismiss",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							finish();
						}
					});
			alert.show();
			return;
		}

		createUI(savedInstanceState);
	}


	public void createUI(Bundle savedInstanceState) {
		mDocListView = new ListView(this);
		pdfPageAdapter = new MyMuPDFPageAdapter(this, core);
		mDocListView.setAdapter(pdfPageAdapter);

		mButtonsView = getLayoutInflater().inflate(R.layout.buttons, null);
		mFilenameView = (TextView) mButtonsView.findViewById(R.id.docNameText);
		loadingPB = (ProgressBar) mButtonsView.findViewById(R.id.loadingPB);
		mTopBarSwitcher = (ViewSwitcher) mButtonsView
				.findViewById(R.id.switcher);
		mTopBarSwitcher.setDisplayedChild(0);
		mTopBarSwitcher.setVisibility(View.VISIBLE);
		loadingPB.setVisibility(View.INVISIBLE);

		mFilenameView.setText("Name:" + mFileName
				+ String.format("    SumPage:%d", core.countPages()));

		RelativeLayout layout = new RelativeLayout(this);
		layout.addView(mDocListView);
		layout.addView(mButtonsView);
		layout.setBackgroundResource(R.drawable.tiled_background);
		setContentView(layout);
	}

	public void onDestroy() {
		if (core != null)
			core.onDestroy();
		core = null;
		super.onDestroy();
	}

	@Override
	protected void dispatchMsgOP(Message msg) {
		super.dispatchMsgOP(msg);
		if (1 == msg.what) {
			Toast.makeText(MuPDFActivity.this, "loading", Toast.LENGTH_SHORT)
					.show();
			loadingPB.setVisibility(View.VISIBLE);
		} else {
			loadingPB.setVisibility(View.INVISIBLE);
		}
	}
}
         4,展示效果【实际应用】

Android内嵌MuPDF打开PDF文件_第2张图片

实际使用说明:

        当前PDF阅读器的实质是一个ListView,从而可以实现当前页面的重新布局,以达到实际需求。如:title栏变更效果,增加“分享”等后续操作。


二、so库的使用

1,导入so库源文件

so库分包有armeabi,arm64-v8a,armeabi-v7a等,是针对不同的ARM设备的包。armeabi,armeabi-v7a是32位ARM设备,arm64-v8a是64位ARM设备。arm64-v8a是向下兼容的,每个包有自己的优化和处理,最理想的条件是每个设备类型都有对应的so库文件。

注意事项是arm64-v8a中一定要有全部的armeabi的源文件,否则在调用到armeabi中独有的就会出错。当存在arm64-v8a中没有armeabi的so库文件时,只能删除整个包,保证程序能够正常运行。

2,关联库文件

	static {
		System.loadLibrary("mupdf");//加载库文件
	}
生命so库文件中存在的方法,从而能够正常使用。后续调用,只是类本身之间的调用,遵循类的规则即可。


三、使用细节注意

        1,包名一致【JNI调用规则】

Java_ + 包名(com.lucyfyr) 类名(HelloWorld) + 接口名(printJNI):必须要按此JNI规范来操作;

so库文件中方法在使用时,必须保证使用环境的包名与so库文件编译生成的包名一致。


        2,so库的注意事项

注意事项:arm64-v8a中一定要有全部的armeabi的源文件,否则在调用到armeabi中独有文件方法时就会出错。当存在arm64-v8a中没有armeabi的so库文件时,只能删除整个包,保证程序能够正常运行。或者重新编译生成so库文件。


这里是源码



如果你犹豫要不要买一件东西只是因为它比较贵,那就买下来。如果你想买一件东西

只是因为它非常便宜划算那就不要买。 

不要用价钱去评判一样东西,而要看它的价值!


你可能感兴趣的:(Android进阶等级二)