WebView von Android lädt PDF-Links, um eine Vorschau der PDF-Dateien anzuzeigen


Vorwort

Die Webansicht von Android unterstützt das Laden von PDFs überhaupt nicht. Android unterscheidet sich von iOS. iOS lädt PDFs, egal ob lokal oder online, sie können direkt mit der Webansicht gerendert werden, aber Android kann das nicht, also müssen wir uns zurückhalten . Es gibt auch viele Methoden wie PDFview, MuPDF usw. von Drittanbietern, dies wird jedoch nicht empfohlen. Das APK-Volumen ist beim Import viel größer, daher werden die meisten Szenen über js analysiert und dann die PDF-Datei geladen die Webansicht, also ist die interne Bibliothek klein und nur 2 Mega, fangen wir an.


1. Rendern

Fügen Sie hier eine Bildbeschreibung ein

2. Umsetzungsschritte

1. Erstellen Sie ein neues Asset im Hauptverzeichnis des Projekts

2. Erstellen Sie ein neues js als index.js

var url = location.search.substring(1);

PDFJS.cMapUrl = 'https://unpkg.com/pdfjs-dist@1.9.426/cmaps/';
PDFJS.cMapPacked = true;

var pdfDoc = null;

function createPage() {
    
    
    var div = document.createElement("canvas");
    document.body.appendChild(div);
    return div;
}

function renderPage(num) {
    
    
    pdfDoc.getPage(num).then(function (page) {
    
    
        var viewport = page.getViewport(2.0);
        var canvas = createPage();
        var ctx = canvas.getContext('2d');

        canvas.height = viewport.height;
        canvas.width = viewport.width;

        page.render({
    
    
            canvasContext: ctx,
            viewport: viewport
        });
    });
}

PDFJS.getDocument(url).then(function (pdf) {
    
    
    pdfDoc = pdf;
    for (var i = 1; i <= pdfDoc.numPages; i++) {
    
    
        renderPage(i)
    }
});


3. Erstellen Sie einen neuen HTML-Code als index.html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=4.0,user-scalable=no"/>
    <title>Document</title>
    <style type="text/css">
        canvas {
    
    
            width: 100%;
            height: 100%;
            border: 1px solid black;
        }
    </style>
    <script src="https://unpkg.com/[email protected]/build/pdf.min.js"></script>
    <script type="text/javascript" src="index.js"></script>
</head>
<body>
</body>
</html>


4.xml-Layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">

    <include
        android:id="@+id/include"
        layout="@layout/title_layout" />

    <WebView
        android:id="@+id/pdfwebview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/gosign"
        android:layout_below="@+id/include" />

    <TextView
        android:id="@+id/gosign"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:layout_centerInParent="true"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="10dp"
        android:layout_marginRight="30dp"
        android:layout_marginBottom="30dp"
        android:background="@drawable/blackground_home_blue"
        android:gravity="center"
        android:text="Go Sign"
        android:textColor="#ffffff"
        android:textSize="16dp" />

</RelativeLayout>

4. Aktivitätsklasse (Kotlin)

注意:activity代码要点在于WebSettings设置的参数和loadUrl()加载URL时加"file:///android_asset/index.html?"

class PDFWebViewActivity : Activity(), OnClickListener {
    
    

    private lateinit var relative_back: RelativeLayout
    private lateinit var text_title: TextView
    private lateinit var url: String//接收URL
    private lateinit var title: String//接收title
    private lateinit var pdfwebview: WebView
    private lateinit var gosign: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        //去掉状态栏
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    
    
            val decorView = window.decorView
            val option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            decorView.systemUiVisibility = option
            window.statusBarColor = Color.parseColor("#00000000")
        }
        //修改状态栏文字为黑色
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
                View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        setContentView(R.layout.pdfwebviewlayout)
        url = intent.getStringExtra("url")!!.trim {
    
     it <= ' ' }
        title = intent.getStringExtra("title")!!.trim {
    
     it <= ' ' }
        instantiation()
    }

    fun instantiation() {
    
    
        EventBus.getDefault().register(this)
        relative_back = findViewById(R.id.relative_back)
        text_title = findViewById(R.id.text_title)
        text_title.text = title
        pdfwebview = findViewById(R.id.pdfwebview)
        gosign = findViewById(R.id.gosign)
        gosign.setOnClickListener(this)
        relative_back.setOnClickListener(this)
        webviewDe(url)
    }

    override fun onClick(v: View?) {
    
    
        when (v?.id) {
    
    
            R.id.relative_back ->
                finish()
        }
    }

    /**
     * webview显示
     */
    @SuppressLint("SetJavaScriptEnabled", "JavascriptInterface")
    private fun webviewDe(url: String) {
    
    
        println("网页url打印:$url")
        val webSettings: WebSettings = pdfwebview.getSettings()
        webSettings.cacheMode = WebSettings.LOAD_DEFAULT
        //设置加载进来的页面自适应手机屏幕
        webSettings.useWideViewPort = true
        webSettings.loadWithOverviewMode = true
        //问题2:基本都需要支持JS
        webSettings.javaScriptEnabled = true
        webSettings.allowFileAccess = true
        //支持通过JS打开新窗口
        webSettings.allowFileAccessFromFileURLs = true
        webSettings.allowUniversalAccessFromFileURLs = true
        webSettings.javaScriptCanOpenWindowsAutomatically = true
        webSettings.setGeolocationEnabled(true)
        webSettings.domStorageEnabled = true
        webSettings.setAppCacheEnabled(false)
        pdfwebview.scrollBarStyle = WebView.SCROLLBARS_OUTSIDE_OVERLAY
        //触摸焦点起作用
        pdfwebview.requestFocus()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    
    
            //http与https的方法
            webSettings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
        }
        // 添加js交互接口类,并起别名 Android
        pdfwebview.addJavascriptInterface(JavascriptImgInterface(), "Android")

        //设置WebChromeClient类
        pdfwebview.webChromeClient = object : WebChromeClient() {
    
    
            //获取网站标题
            override fun onReceivedTitle(view: WebView, title: String) {
    
    
                println("标题在这里$title")
            }

            //图片选取
            override fun onShowFileChooser(
                webView: WebView,
                filePathCallback: ValueCallback<Array<Uri>>,
                fileChooserParams: FileChooserParams,
            ): Boolean {
    
    
                return true
            }
        }
        //设置WebViewClient类
        pdfwebview.webViewClient = object : WebViewClient() {
    
    
            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
    
    
                // 返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器
                view.loadUrl(url)
                return true
            }

            //设置加载前的函数 kotlin这里favicon: Bitmap?的Bitmap?必须加?
            override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
    
    
                if (!this@PDFWebViewActivity.isFinishing) 
                {
    
    
                    println("开始加载了")
                    DialogUtils.showLoadingDialog(this@PDFWebViewActivity)
                }
            }

            //设置结束加载函数
            override fun onPageFinished(view: WebView, url: String) {
    
    
                println("结束加载了")
                try {
    
    
                    DialogUtils.hideLoadingDialog()
                } catch (e: Exception) {
    
    
                }
            }
        }
        pdfwebview.loadUrl("file:///android_asset/index.html?$url")
    }

    class JavascriptImgInterface {
    
    
        /**
         * 注意: 在Android4.2极其以上系统需要给提供js调用的方法前加入一个注释:@JavaScriptInterface;
         * 在虚拟机当中 Javascript调用Java方法会检测这个anotation,
         * 如果方法被标识@JavaScriptInterface则Javascript可以成功调用这个Java方法,否则调用不成功。
         */
        //js调用Android方法给web返回Token值
        @JavascriptInterface
        open fun Android_Token(): String? {
    
    
            println("打印的token:" + SpUtil.get(ConstantUtil.TOKEN, ""))
            return SpUtil.get(ConstantUtil.TOKEN, "")
        }

    }
}

5. Aktivitätsklasse (Java)

注意:activity代码要点在于WebSettings设置的参数和loadUrl()加载URL时加"file:///android_asset/index.html?"


public class PDFWebViewActivity extends Activity implements View.OnClickListener {
    
    

    private String url;//接收URL
    private String title;//接收title
    private ImageView left_black_risk;//返回键
    private TextView text_title;//title
    private RelativeLayout gosign;//去签名
    private static String message;//返回消息
    private WebView webviewx5;//webview

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        //去掉状态栏
        if (Build.VERSION.SDK_INT >= 21) {
    
    
            View decorView = getWindow().getDecorView();
            int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
            decorView.setSystemUiVisibility(option);
            getWindow().setStatusBarColor(Color.parseColor("#00000000"));
        }
        //修改状态栏文字为黑色
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                        View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        setContentView(R.layout.pdfwebviewlayout);
        url = getIntent().getStringExtra("url").trim();
        title = getIntent().getStringExtra("title").trim();
        instantiation();
    }

    private void instantiation() {
    
    
        webviewx5 = findViewById(R.id.webview);
        left_black_risk = findViewById(R.id.left_black_risk);
        text_title = findViewById(R.id.text_title);
        gosign = findViewById(R.id.gosign);
        text_title.setText(title);
        left_black_risk.setOnClickListener(this);
        gosign.setOnClickListener(this);
        webviewDe(url);
    }

    /**
     * webview显示
     */
    @SuppressLint({
    
    "SetJavaScriptEnabled", "JavascriptInterface"})
    private void webviewDe(String url) {
    
    
        System.out.println("网页url打印:" + url);
        WebSettings webSettings = webviewx5.getSettings();
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
        //设置加载进来的页面自适应手机屏幕
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
        //问题2:基本都需要支持JS
        webSettings.setJavaScriptEnabled(true);
        webSettings.setAllowFileAccess(true);
        //支持通过JS打开新窗口
        webSettings.setAllowFileAccessFromFileURLs(true);
        webSettings.setAllowUniversalAccessFromFileURLs(true);
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setGeolocationEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setAppCacheEnabled(false);

        webviewx5.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        //触摸焦点起作用
        webviewx5.requestFocus();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    
    
            //http与https的方法
            webSettings.setMixedContentMode(MIXED_CONTENT_ALWAYS_ALLOW);
        }
        // 添加js交互接口类,并起别名 Android
        webviewx5.addJavascriptInterface(new JavascriptImgInterface(), "Android");

        //设置WebChromeClient类
        webviewx5.setWebChromeClient(new WebChromeClient() {
    
    


            //获取网站标题
            @Override
            public void onReceivedTitle(WebView view, String title) {
    
    
                System.out.println("标题在这里" + title);
            }

            //图片选取
            @Override
            public boolean onShowFileChooser(WebView webView,
                                             ValueCallback<Uri[]> filePathCallback,
                                             FileChooserParams fileChooserParams) {
    
    
                return true;
            }
        });
        //设置WebViewClient类
        webviewx5.setWebViewClient(new WebViewClient() {
    
    

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
    
    
                // 返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器
                view.loadUrl(url);
                return true;
            }

            //设置加载前的函数
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
    
    
                if (!PDFWebViewActivity.this.isFinishing())//xActivity即为本界面的Activity
                {
    
    
                    System.out.println("开始加载了");
                    DialogUtils.showLoadingDialog(PDFWebViewActivity.this);
                }
            }

            //设置结束加载函数
            @Override
            public void onPageFinished(WebView view, String url) {
    
    
                System.out.println("结束加载了");
                try {
    
    
                    DialogUtils.hideLoadingDialog();
                } catch (Exception e) {
    
    

                }
            }
        });
        webviewx5.loadUrl("file:///android_asset/index.html?" + url);
    }

    public class JavascriptImgInterface {
    
    
        /**
         * 注意: 在Android4.2极其以上系统需要给提供js调用的方法前加入一个注释:@JavaScriptInterface;
         * 在虚拟机当中 Javascript调用Java方法会检测这个anotation,
         * 如果方法被标识@JavaScriptInterface则Javascript可以成功调用这个Java方法,否则调用不成功。
         */
        //js调用Android方法给web返回Token值
        @JavascriptInterface
        public String Android_Token() {
    
    
            System.out.println("打印的token:" + SpUtil.get(ConstantUtil.TOKEN, ""));
            return SpUtil.get(ConstantUtil.TOKEN, "");
        }

        //js调用Android方法下载apk
        @JavascriptInterface
        public String Android_DownloadApk(String url) {
    
    
            //方式一:代码实现跳转
            Intent intent = new Intent();
            //通过intent发送数据
            intent.setAction("android.intent.action.VIEW");
            //创建一个链接  链接.语法解析
            Uri content_url = Uri.parse(url);
            //通过intent接受
            intent.setData(content_url);
            //开始于当前intent
            startActivity(intent);
            return url;
        }
    }

    @Override
    public void onClick(View view) {
    
    
        switch (view.getId()) {
    
    
            //返回键
            case R.id.left_black_risk:
                finish();
                break;
            //去签名
            case R.id.gosign:
                break;
        }
    }
}


Zusammenfassen

Das Obige dient dazu, eine Vorschau der PDF-Datei durch Laden von js anzuzeigen. Es gibt Kommentare und Sie können es langsam verstehen. Wenn Sie Fragen haben, fragen Sie mich bitte und korrigieren Sie mich!

Je suppose que tu aimes

Origine blog.csdn.net/Android_Cll/article/details/131641229
conseillé
Classement