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

Android 从webview打开pdf文件时,如何使用MuPDF库打开pdf文件,android,webview,mupdf,Android,Webview,Mupdf,我用MuPDF库制作了一个演示应用程序,但当应用程序打开时,它会从设备存储中打开一个pdf文件。我使用webview制作了另一个应用程序,从assets文件夹中打开htmls。我想用这个库在我链接到pdf文件的按钮被点击时打开一个阅读器。我找不到任何有关这方面的教程,我真的非常感谢任何帮助 webview应用程序的MainActivity.java: package epsnotes.com.epsnotes; import android.support.v7.app.AppCompatAct

我用MuPDF库制作了一个演示应用程序,但当应用程序打开时,它会从设备存储中打开一个pdf文件。我使用webview制作了另一个应用程序,从assets文件夹中打开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应用程序的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演示应用程序的activity_main.xml:

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);
}
}
<?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>

编辑-开始:

要获取Java中的文件名,请使用JavascriptInterface传递文件名。 定义接口类(在MainActivity内部)

之后,实现loadPdf方法(在MainActivity内部)

然后,实现一个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.)将渲染位图填充到ImageView中:

XML(活动XML):


如果设备上没有PDF,请使用您最喜欢的HTTP客户端API(例如,
HttpUrlConnection
,OkHttp)下载PDF,然后查看。我在应用程序的资产文件夹中有PDF,还有我在webview中使用的htmls。我已经将一个按钮链接到pdf,但当我运行应用程序并点击它时,什么都没有发生。当我点击按钮时,我想让MuPDF打开一个读卡器。@Yoseph Mandefro:请显示您迄今为止如何实现它的代码。@user2281606我添加了代码。如果你对我的问题有任何疑问,请提问。我很感激你的关心。所以PDF将以新的布局打开。要打开布局,必须设置一个特定PDF的路径,这就是问题所在。我的webview HTML中有多个PDF。我想要一个PDF打开时,它的html按钮是点击。只要能完成任务,任何解决方案都适合我。“必须为版面设置一个特定PDF的路径才能打开它,这就是问题所在。我的webview htmls中有多个PDF。”我不明白……你的PDF文件在哪里,本地还是服务器?您是否使用HTML中的a-href链接到PDF文件?本地,PDF文件与用于webview的htmls一起位于资产文件夹中。我实际上使用的是一个web生成器,我将不同的按钮链接到不同的PDF。我确信它使用的是a-href。我会将代码复制到项目中,并将结果反馈给您。
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();
    }
}
function passPdfFileToJava(name) {
    if (typeof Android != "undefined"){ 
        if (Android.passPdfFileName!= "undefined") {
            Android.passPdfFileName(name);
        }
    }
}
/**
* 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);
}
<?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>
@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));
        }
    });
}