从webview打开pdf文件时,如何使用MuPDF库打开pdf文件

时间:2017-03-25 17:39:15

标签: android webview mupdf

我使用MuPDF库制作了一个演示应用程序,但是当应用程序打开时,它会从设备存储中打开一个pdf文件。我使用webview创建了另一个应用程序来打开资产文件夹中的htmls。每当我点击链接到pdf文件的按钮时,我想使用该库打开一个阅读器。我找不到任何关于此的教程,我真的很感激任何帮助。

用于webview应用程序的MainActivity.java:

package epsnotes.com.epsnotes;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
private WebView mywebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mywebView = (WebView)findViewById(R.id.webView);
    WebSettings webSettings = mywebView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    mywebView.loadUrl("file:///android_asset/index.html");
    mywebView.setWebViewClient(new WebViewClient());
}

@Override
public void onBackPressed() {
    if(mywebView.canGoBack())  {
        mywebView.goBack();
    } else {
        super.onBackPressed();
    }
}
}

webview app的activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="epsnotes.com.epsnotes.MainActivity">

<WebView
    android:id="@+id/webView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true" />
</RelativeLayout>

MuPDF演示应用的MainActivity.java:

package yoseman.com.mupdfdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.RelativeLayout;

import com.artifex.mupdfdemo.FilePicker;
import com.artifex.mupdfdemo.MuPDFCore;
import com.artifex.mupdfdemo.MuPDFPageAdapter;
import com.artifex.mupdfdemo.MuPDFReaderView;

public class MainActivity extends AppCompatActivity {

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

    RelativeLayout layout = (RelativeLayout) findViewById(R.id.main_layout);

    MuPDFCore core = null;
    try {
        core = new MuPDFCore(this, "/storage/emulated/0/Download/AMHMOE11.pdf");
    } catch (Exception e) {
        e.printStackTrace();
    }
    MuPDFReaderView reader = new MuPDFReaderView(this);
    reader.setAdapter(new MuPDFPageAdapter(this, new FilePicker.FilePickerSupport() {
        @Override
        public void performPickFor(FilePicker filePicker) {

        }
    }, core));
    layout.addView(reader);
}
}

MuPDF演示应用的activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="yoseman.com.mupdfdemo.MainActivity">


</RelativeLayout>

1 个答案:

答案 0 :(得分:0)

编辑 - 开始:

要使用Java获取文件名,请使用JavascriptInterface传递名称。 定义Interface-Class(在MainActivity中)。

public static class PdfJavascriptInterface {

    WeakReference<MainActivity> mainActivity;

    public PdfJavascriptInterface (MainActivity mainactivity) {

        this.mainActivity = new WeakReference<>(mainActivity)
    }

    @JavascriptInterface
    public void passPdfFileName(String name) {
        if (this.mainActivity.get() != null) {

             this.mainActivity.get().loadPdf(name);
        }
    }
} 

在您的webView上添加JavascriptInterface:

webView.addJavascriptInterface(new PdfJavascriptInterface(this), "Android");

之后,实现loadPdf方法(在MainActivity中)。

public void loadPdf (String name) {

    try {

        InputStream pdfStream = this.getAssets().open(name);
        //MuPDFCore class has two constructors:
        // 1. MuPDFCore(Context context, String filename) 
        // 2. MuPDFCore(Context context, byte buffer[], String magic)
        // this time we take nr. two. Because of that you need byte array
        // i wrote it down quickly, no good style here :-)
       ByteArrayOutputStream bos = new ByteArrayOutputStream();
       byte[] buffer = new byte[1024];
       while (true) {
           int read = pdfStream .read(buffer);
           if (read  == -1) break;
           bos.write(buffer, 0, read);
       }

       final byte[] pdfByteArray = bos.toByteArray(); 

       //i will not rewrite render method, thats your task :-)
       new Thread(new Runnable() {

           @Override
           public void run() {

               render (..., pdfByteArray, ...);
               // in render method
               // core = new MuPDFCore(context.getApplicationContext(), 
               // pdfByteArray, null);
           }
       }).start();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

然后,实现一个javascript方法,在onClick事件上调用:

function passPdfFileToJava(name) {
    if (typeof Android != "undefined"){ 
        if (Android.passPdfFileName!= "undefined") {
            Android.passPdfFileName(name);
        }
    }
}

编辑 - 结束

我根本不使用MuPDFReaderView,我将渲染的图像插入到我自己的布局中。 因此,我不知道它是否适合您。

1。)以适当的尺寸渲染pdf:

/**
* renders PDF file, start this method on a worker thread
* @param callback Callback is a interface implemented by your activity
* @param context Context
* @param pathToPdfFile String
* @param width int 
* @param height int
*/
public void render (Callback renderCallback, Context context, String pathToPdfFile, int width, int height) {

    MuPDFCore core;
    try {
        //do not use hardcoded paths ("/storage/emulated/0/Download/)
        // use something like
        //Environment
        //.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
        //.getAbsolutePath() + 
        //File.separator + 
        //"AMHMOE11.pdf"          
        core = new MuPDFCore(context.getApplicationContext(), pathToPdfFile);  

        //Assuming here you are in portrait mode: height is the longer value of 
        //DisplayMetrics.widthPixels and DisplayMetrics.heightPixels
        Bitmap bm = Bitmap.createBitmap(width, height, Config.ARGB_8888);
        // you want to render whole page, patches == 0
        core.drawPage(bm, width, height, 0, 0, width, height, core.new Cookie());
        core.onDestroy();
        callback.rendered(bm);
    } catch (Exception e) {
        e.printStackTrace();
}


public interface Callback {

    public void rendered (Bitmap bm);
}

2。)将Bitmap渲染到ImageView:

XML(activity_xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/main_layout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context="yoseman.com.mupdfdemo.MainActivity">

  <ImageView
   android:id="@+id/pdf_bitmap"
   android:layout_width="match_parent"
   android:layout_height="match_parent" />
</RelativeLayout>

Java(MainActivity.java):

@Override
public void rendered (final Bitmap bm) {

    runOnUiThread(new Runnable() {

        @Override
        public void run() {


            ImageView imageView = (ImageView)MainActivity.this.findViewById(R.id.pdf_bitmap);
            imageView.setBackground(new BitmapDrawable(MainActivity.this.getResources(), bm));
        }
    });
}