文章目录
Android的webview压根就不支持加载pdf,Android与iOS不同,iOS加载pdf,不管本地还是在线,直接使用webview渲染就可以了,而Android却做不到,所以我们必须得扣脑壳了。方法也有很多种,比如第三方PDFview,MuPDF等,但是不推荐,引入进去apk体积会大很多,所以大多场景都是通过js解析,然后在webview中加载PDF文件,所以内库很小也就2兆多,那我们就开始吧。
1.在项目main目录下新建一个assets
2.新建一个js为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.新建一个HTML为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/pdfjs-dist@1.9.426/build/pdf.min.js"></script> <script type="text/javascript" src="index.js"></script></head><body></body></html>
4.xml布局
<?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.Activity类(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() } } @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 { //js调用Android方法给web返回Token值 @JavascriptInterface open fun Android_Token(): String? { println("打印的token:" + SpUtil.get(ConstantUtil.TOKEN, "")) return SpUtil.get(ConstantUtil.TOKEN, "") } }}
5.Activity类(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); } @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 { //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; } }}
以上便是通过加载js的方式预览PDF文件了,都有注释自己慢慢去理解,有问题欢迎提出并指正!
来源地址:https://blog.csdn.net/Android_Cll/article/details/131641229