Как использовать библиотеку MuPDF для открытия файлов PDF, когда файл PDF открывается из веб-просмотра

Я сделал демонстрационное приложение с библиотекой MuPDF, но оно открывает один файл PDF из хранилища устройства при открытии приложения. Я сделал еще одно приложение, используя веб-просмотр, чтобы открывать html из папки с ресурсами. И я хочу использовать библиотеку, чтобы открывать программу чтения всякий раз, когда нажимается кнопка, которую я связал с файлом PDF. Я не смог найти никаких руководств по этому поводу, и я был бы очень признателен за любую помощь.

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

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>

MainActivity.java для демонстрационного приложения MuPDF:

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

activity_main.xml для демонстрационного приложения MuPDF:

<?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>

person yt247    schedule 25.03.2017    source источник
comment
Если PDF-файл отсутствует на устройстве, загрузите PDF-файл с помощью своего любимого API-интерфейса HTTP-клиента (например, HttpUrlConnection, OkHttp), а затем просмотрите его.   -  person CommonsWare    schedule 25.03.2017
comment
У меня есть PDF-файл в папке ресурсов приложения вместе с HTML-файлами, которые я использую в веб-просмотре. Я связал кнопку с pdf, но когда я запускаю приложение и нажимаю на него, ничего не происходит. Я хочу, чтобы MuPDF открывал программу чтения, когда я нажимаю на кнопку.   -  person yt247    schedule 25.03.2017
comment
@Yoseph Mandefro: пожалуйста, покажите код, как вы его реализовали.   -  person A.D.    schedule 27.03.2017
comment
@ user2281606 Я добавил код. Если есть вопросы по моему вопросу, спрашивайте. Я ценю вашу заботу.   -  person yt247    schedule 27.03.2017


Ответы (1)


ИЗМЕНИТЬ — Начало:

Чтобы получить имя файла в Java, передайте имя с помощью JavascriptInterface. Определите свой класс интерфейса (внутри 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);
        }
    }
} 

Добавьте JavascriptInterface в свой webView:

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 (деятельность_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));
        }
    });
} 
person A.D.    schedule 28.03.2017
comment
Таким образом, PDF-файл откроется в новом макете. Путь к одному конкретному PDF-файлу должен быть установлен для макета, чтобы открыть его, вот в чем проблема. В моих HTML-файлах веб-просмотра есть несколько PDF-файлов. Я хочу, чтобы один PDF-файл открывался при нажатии кнопки html для него. Любое решение подходит для меня, пока оно выполняет свою работу. - person yt247; 28.03.2017
comment
Путь к одному конкретному PDF-файлу должен быть установлен для макета, чтобы открыть его, вот в чем проблема. В моих HTML-файлах веб-просмотра есть несколько PDF-файлов. Я не понимаю, что... где ваши файлы PDF, локальные или серверные? Вы связываете файлы HTML с файлами PDF с помощью a-href? - person A.D.; 28.03.2017
comment
Локальные файлы PDF находятся в папке с ресурсами вместе с html для веб-просмотра. На самом деле я использую веб-конструктор и привязал разные кнопки к разным PDF-файлам. Я уверен, что он использует a-href. - person yt247; 28.03.2017
comment
‹a class=mbr-buttons__btn btn btn-lg btn-default анимированная задержка постепенного появления входа href=AMHMOE11.pdf›AMHARIC‹/a› - person yt247; 29.03.2017
comment
Я скопирую коды в проект и вернусь к вам с результатами. - person yt247; 30.03.2017